mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-03 20:46:28 +00:00
Implement deferred ICE reinvite response when the ICE session isn't yet completed.
This commit is contained in:
parent
3a0bcc675a
commit
6c7c56271a
6 changed files with 67 additions and 5 deletions
|
|
@ -134,6 +134,7 @@ protected:
|
|||
bool broken = false;
|
||||
bool deferIncomingNotification = false;
|
||||
bool deferUpdate = false;
|
||||
bool deferUpdateInternal = false;
|
||||
bool needLocalIpRefresh = false;
|
||||
bool nonOpError = false; /* Set when the LinphoneErrorInfo was set at higher level than sal */
|
||||
bool notifyRinging = true;
|
||||
|
|
|
|||
|
|
@ -467,9 +467,10 @@ void CallSessionPrivate::updated (bool isUpdate) {
|
|||
void CallSessionPrivate::updatedByRemote () {
|
||||
L_Q();
|
||||
setState(CallSession::State::UpdatedByRemote,"Call updated by remote");
|
||||
if (deferUpdate) {
|
||||
if (state == CallSession::State::UpdatedByRemote)
|
||||
lInfo() << "CallSession [" << q << "]: UpdatedByRemoted was signaled but defered. LinphoneCore expects the application to call CallSession::acceptUpdate() later";
|
||||
if (deferUpdate || deferUpdateInternal) {
|
||||
if (state == CallSession::State::UpdatedByRemote && !deferUpdateInternal){
|
||||
lInfo() << "CallSession [" << q << "]: UpdatedByRemoted was signaled but defered. LinphoneCore expects the application to call linphone_call_accept_update() later";
|
||||
}
|
||||
} else {
|
||||
if (state == CallSession::State::UpdatedByRemote)
|
||||
q->acceptUpdate(nullptr);
|
||||
|
|
|
|||
|
|
@ -254,7 +254,6 @@ private:
|
|||
int sendDtmf ();
|
||||
|
||||
void stunAuthRequestedCb (const char *realm, const char *nonce, const char **username, const char **password, const char **ha1);
|
||||
|
||||
private:
|
||||
static const std::string ecStateStore;
|
||||
static const int ecStateMaxLen;
|
||||
|
|
@ -325,6 +324,7 @@ private:
|
|||
bool automaticallyPaused = false;
|
||||
bool pausedByApp = false;
|
||||
bool recordActive = false;
|
||||
bool incomingIceReinvitePending = false;
|
||||
|
||||
std::string onHoldFile;
|
||||
|
||||
|
|
|
|||
|
|
@ -382,6 +382,8 @@ void MediaSessionPrivate::updated (bool isUpdate) {
|
|||
CallSessionPrivate::updated(isUpdate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MediaSessionPrivate::updating (bool isUpdate) {
|
||||
L_Q();
|
||||
SalMediaDescription *rmd = op->get_remote_media_description();
|
||||
|
|
@ -702,6 +704,10 @@ shared_ptr<Participant> MediaSessionPrivate::getMe () const {
|
|||
|
||||
void MediaSessionPrivate::setState (CallSession::State newState, const string &message) {
|
||||
L_Q();
|
||||
SalMediaDescription *rmd;
|
||||
|
||||
lInfo()<<"MediaSessionPrivate::setState";
|
||||
|
||||
/* Take a ref on the session otherwise it might get destroyed during the call to setState */
|
||||
shared_ptr<CallSession> sessionRef = q->getSharedFromThis();
|
||||
if ((newState != state) && (newState != CallSession::State::StreamsRunning))
|
||||
|
|
@ -709,6 +715,21 @@ void MediaSessionPrivate::setState (CallSession::State newState, const string &m
|
|||
CallSessionPrivate::setState(newState, message);
|
||||
if (listener)
|
||||
listener->onCallSessionStateChangedForReporting(q->getSharedFromThis());
|
||||
switch(newState){
|
||||
case CallSession::State::UpdatedByRemote:
|
||||
/*Handle specifically the case of an incoming ICE-concluded reINVITE*/
|
||||
lInfo()<<"Checking for ICE reINVITE";
|
||||
rmd = op->get_remote_media_description();
|
||||
if (iceAgent && rmd != nullptr && iceAgent->checkIceReinviteNeedsDeferedResponse(rmd)){
|
||||
deferUpdate = true;
|
||||
deferUpdateInternal = true;
|
||||
incomingIceReinvitePending = true;
|
||||
lInfo()<<"CallSession [" << q << "]: ICE reinvite received, but one or more check-lists are not completed. Response will be sent later, when ICE has completed";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -2191,11 +2212,14 @@ void MediaSessionPrivate::handleIceEvents (OrtpEvent *ev) {
|
|||
OrtpEventData *evd = ortp_event_get_data(ev);
|
||||
if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
|
||||
if (iceAgent->hasCompletedCheckList()) {
|
||||
/* At least one ICE session has succeeded, so perform a call update */
|
||||
/* The ICE session has succeeded, so perform a call update */
|
||||
if (iceAgent->isControlling() && q->getCurrentParams()->getPrivate()->getUpdateCallWhenIceCompleted()) {
|
||||
MediaSessionParams newParams(*getParams());
|
||||
newParams.getPrivate()->setInternalCallUpdate(true);
|
||||
q->update(&newParams);
|
||||
}else if (!iceAgent->isControlling() && incomingIceReinvitePending){
|
||||
q->acceptUpdate(nullptr);
|
||||
incomingIceReinvitePending = false;
|
||||
}
|
||||
startDtlsOnAllStreams();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -738,4 +738,35 @@ void IceAgent::updateIceStateInCallStatsForStream (LinphoneCallStats *stats, Ice
|
|||
}
|
||||
}
|
||||
|
||||
bool IceAgent::checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md){
|
||||
int i,j;
|
||||
IceCheckList *cl;
|
||||
|
||||
if (!iceSession) return false;
|
||||
|
||||
if (ice_session_state(iceSession) != IS_Running ) return false;
|
||||
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
SalStreamDescription *stream = &md->streams[i];
|
||||
cl = ice_session_check_list(iceSession, i);
|
||||
|
||||
if (cl==NULL) continue;
|
||||
if (stream->ice_mismatch == TRUE) {
|
||||
return false;
|
||||
}
|
||||
if (stream->rtp_port == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ice_check_list_state(cl) != ICL_Running) continue;
|
||||
|
||||
for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; j++) {
|
||||
const SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[j];
|
||||
if (remote_candidate->addr[0] != '\0') return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -66,6 +66,11 @@ public:
|
|||
void updateFromRemoteMediaDescription (const SalMediaDescription *localDesc, const SalMediaDescription *remoteDesc, bool isOffer);
|
||||
void updateIceStateInCallStats ();
|
||||
void updateLocalMediaDescriptionFromIce (SalMediaDescription *desc);
|
||||
/*
|
||||
* Checks if an incoming offer with ICE needs a delayed answer, because the ice session hasn't completed yet with
|
||||
* connecvity checks.
|
||||
*/
|
||||
bool checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md);
|
||||
|
||||
private:
|
||||
void addLocalIceCandidates (int family, const char *addr, IceCheckList *audioCl, IceCheckList *videoCl, IceCheckList *textCl);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue