From 7e15914c28b2233dd4cee12e87c8c73e83ec0657 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 8 Sep 2017 16:59:04 +0200 Subject: [PATCH] Handle pause and resume in C++ objects. --- coreapi/linphonecall.c | 98 +---------------- src/call/call-listener.h | 1 + src/call/call-p.h | 1 + src/call/call.cpp | 14 +++ src/call/call.h | 2 + src/conference/conference-p.h | 1 + src/conference/conference.cpp | 5 + .../session/call-session-listener.h | 1 + src/conference/session/call-session-p.h | 2 +- src/conference/session/media-session-p.h | 4 +- src/conference/session/media-session.cpp | 103 ++++++++++++++++-- src/conference/session/media-session.h | 2 + 12 files changed, 128 insertions(+), 106 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index eabe1e338..e245813aa 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1198,110 +1198,16 @@ RtpTransport * linphone_call_get_meta_rtcp_transport(const LinphoneCall *call, i } LinphoneStatus linphone_call_pause(LinphoneCall *call) { -#if 0 - int err = _linphone_call_pause(call); - if (err == 0) call->paused_by_app = TRUE; - return err; -#else - return 0; -#endif + return linphone_call_get_cpp_obj(call)->pause(); } /* Internal version that does not play tone indication*/ int _linphone_call_pause(LinphoneCall *call) { -#if 0 - LinphoneCore *lc; - const char *subject = NULL; - - if ((call->state != LinphoneCallStreamsRunning) && (call->state != LinphoneCallPausedByRemote)) { - ms_warning("Cannot pause this call, it is not active."); - return -1; - } - if (sal_media_description_has_dir(call->resultdesc, SalStreamSendRecv)) { - subject = "Call on hold"; - } else if (sal_media_description_has_dir(call->resultdesc, SalStreamRecvOnly)) { - subject = "Call on hold for me too"; - } else { - ms_error("No reason to pause this call, it is already paused or inactive."); - return -1; - } - - lc = linphone_call_get_core(call); - call->broken = FALSE; - linphone_call_set_state(call, LinphoneCallPausing, "Pausing call"); - linphone_call_make_local_media_description(call); - sal_call_set_local_media_description(call->op, call->localdesc); - if (sal_call_update(call->op, subject, FALSE) != 0) { - linphone_core_notify_display_warning(lc, _("Could not pause the call")); - } - lc->current_call = NULL; - linphone_core_notify_display_status(lc, _("Pausing the current call...")); - if (call->audiostream || call->videostream || call->textstream) - linphone_call_stop_media_streams(call); - call->paused_by_app = FALSE; return 0; -#else - return 0; -#endif } LinphoneStatus linphone_call_resume(LinphoneCall *call) { -#if 0 - LinphoneCore *lc; - const char *subject = "Call resuming"; - char *remote_address; - char *display_status; - - if (call->state != LinphoneCallPaused) { - ms_warning("we cannot resume a call that has not been established and paused before"); - return -1; - } - lc = linphone_call_get_core(call); - if (linphone_call_params_get_in_conference(call->params) == FALSE) { - if (linphone_core_sound_resources_locked(lc)) { - ms_warning("Cannot resume call %p because another call is locking the sound resources.", call); - return -1; - } - linphone_core_preempt_sound_resources(lc); - ms_message("Resuming call %p", call); - } - - call->was_automatically_paused = FALSE; - call->broken = FALSE; - - /* Stop playing music immediately. If remote side is a conference it - prevents the participants to hear it while the 200OK comes back. */ - if (call->audiostream) audio_stream_play(call->audiostream, NULL); - - linphone_call_make_local_media_description(call); - if (!lc->sip_conf.sdp_200_ack) { - sal_call_set_local_media_description(call->op, call->localdesc); - } else { - sal_call_set_local_media_description(call->op, NULL); - } - sal_media_description_set_dir(call->localdesc, SalStreamSendRecv); - if (linphone_call_params_get_in_conference(call->params) && !linphone_call_params_get_in_conference(call->current_params)) subject = "Conference"; - if (sal_call_update(call->op, subject, FALSE) != 0) { - return -1; - } - linphone_call_set_state(call, LinphoneCallResuming,"Resuming"); - if (linphone_call_params_get_in_conference(call->params) == FALSE) - lc->current_call = call; - remote_address = linphone_call_get_remote_address_as_string(call); - display_status = ms_strdup_printf("Resuming the call with with %s", remote_address); - ms_free(remote_address); - linphone_core_notify_display_status(lc, display_status); - ms_free(display_status); - - if (lc->sip_conf.sdp_200_ack) { - /* We are NOT offering, set local media description after sending the call so that we are ready to - process the remote offer when it will arrive. */ - sal_call_set_local_media_description(call->op, call->localdesc); - } - return 0; -#else - return 0; -#endif + return linphone_call_get_cpp_obj(call)->resume(); } static void terminate_call(LinphoneCall *call) { diff --git a/src/call/call-listener.h b/src/call/call-listener.h index 8e7d36bdd..f20ac5c2b 100644 --- a/src/call/call-listener.h +++ b/src/call/call-listener.h @@ -41,6 +41,7 @@ public: virtual void statsUpdated (const LinphoneCallStats *stats) = 0; + virtual void resetCurrentCall () = 0; virtual void setCurrentCall () = 0; virtual void firstVideoFrameDecoded () = 0; diff --git a/src/call/call-p.h b/src/call/call-p.h index 682b545c2..5233a0863 100644 --- a/src/call/call-p.h +++ b/src/call/call-p.h @@ -69,6 +69,7 @@ public: void statsUpdated (const LinphoneCallStats *stats); + void resetCurrentCall (); void setCurrentCall (); void firstVideoFrameDecoded (); diff --git a/src/call/call.cpp b/src/call/call.cpp index c55cc0999..8c638c909 100644 --- a/src/call/call.cpp +++ b/src/call/call.cpp @@ -162,6 +162,10 @@ void CallPrivate::statsUpdated (const LinphoneCallStats *stats) { linphone_call_notify_stats_updated(lcall, stats); } +void CallPrivate::resetCurrentCall () { + core->current_call = nullptr; +} + void CallPrivate::setCurrentCall () { if (lcall) core->current_call = lcall; @@ -226,6 +230,16 @@ LinphoneStatus Call::decline (const LinphoneErrorInfo *ei) { return d->getActiveSession()->decline(ei); } +LinphoneStatus Call::pause () { + L_D(Call); + return static_cast(d->getActiveSession().get())->pause(); +} + +LinphoneStatus Call::resume () { + L_D(Call); + return static_cast(d->getActiveSession().get())->resume(); +} + void Call::sendVfuRequest () { L_D(Call); static_cast(d->getActiveSession().get())->sendVfuRequest(); diff --git a/src/call/call.h b/src/call/call.h index ee6c2f658..acf2d0c0f 100644 --- a/src/call/call.h +++ b/src/call/call.h @@ -49,6 +49,8 @@ public: LinphoneStatus acceptUpdate (const std::shared_ptr msp); LinphoneStatus decline (LinphoneReason reason); LinphoneStatus decline (const LinphoneErrorInfo *ei); + LinphoneStatus pause (); + LinphoneStatus resume (); void sendVfuRequest (); void startRecording (); void stopRecording (); diff --git a/src/conference/conference-p.h b/src/conference/conference-p.h index f97cf84be..6de840e21 100644 --- a/src/conference/conference-p.h +++ b/src/conference/conference-p.h @@ -51,6 +51,7 @@ public: virtual void statsUpdated (const LinphoneCallStats *stats); + virtual void resetCurrentSession (const CallSession &session); virtual void setCurrentSession (const CallSession &session); virtual void firstVideoFrameDecoded (const CallSession &session); diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp index 6ca8cbaba..84409427d 100644 --- a/src/conference/conference.cpp +++ b/src/conference/conference.cpp @@ -72,6 +72,11 @@ void ConferencePrivate::statsUpdated (const LinphoneCallStats *stats) { callListener->statsUpdated(stats); } +void ConferencePrivate::resetCurrentSession (const CallSession &session) { + if (callListener) + callListener->resetCurrentCall(); +} + void ConferencePrivate::setCurrentSession (const CallSession &session) { if (callListener) callListener->setCurrentCall(); diff --git a/src/conference/session/call-session-listener.h b/src/conference/session/call-session-listener.h index 676330069..96d96d6f9 100644 --- a/src/conference/session/call-session-listener.h +++ b/src/conference/session/call-session-listener.h @@ -37,6 +37,7 @@ public: virtual void statsUpdated (const LinphoneCallStats *stats) = 0; + virtual void resetCurrentSession (const CallSession &session) = 0; virtual void setCurrentSession (const CallSession &session) = 0; virtual void firstVideoFrameDecoded (const CallSession &session) = 0; diff --git a/src/conference/session/call-session-p.h b/src/conference/session/call-session-p.h index eb5e672a5..47390fda7 100644 --- a/src/conference/session/call-session-p.h +++ b/src/conference/session/call-session-p.h @@ -54,7 +54,7 @@ public: virtual void terminated (); void updated (bool isUpdate); void updatedByRemote (); - void updating (bool isUpdate); + virtual void updating (bool isUpdate); protected: void accept (const std::shared_ptr params); diff --git a/src/conference/session/media-session-p.h b/src/conference/session/media-session-p.h index 44171ebfb..3d7d20bd2 100644 --- a/src/conference/session/media-session-p.h +++ b/src/conference/session/media-session-p.h @@ -46,7 +46,6 @@ public: public: static void stunAuthRequestedCb (void *userData, const char *realm, const char *nonce, const char **username, const char **password, const char **ha1); - void abort (const std::string &errorMsg); void accepted (); void ackReceived (LinphoneHeaders *headers); bool failure (); @@ -213,8 +212,10 @@ private: void reportBandwidth (); void reportBandwidthForStream (MediaStream *ms, LinphoneStreamType type); + void abort (const std::string &errorMsg); void handleIncomingReceivedStateInIncomingNotification (); bool isReadyForInvite () const; + LinphoneStatus pause (); void setTerminated (); LinphoneStatus startAcceptUpdate (LinphoneCallState nextState, const std::string &stateInfo); LinphoneStatus startUpdate (); @@ -287,6 +288,7 @@ private: bool allMuted = false; bool audioMuted = false; + bool automaticallyPaused = false; bool pausedByApp = false; bool playingRingbackTone = false; bool recordActive = false; diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 6ae54fb87..69df709dd 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -117,14 +117,6 @@ void MediaSessionPrivate::stunAuthRequestedCb (void *userData, const char *realm // ----------------------------------------------------------------------------- -void MediaSessionPrivate::abort (const string &errorMsg) { -#if 0 - linphone_core_stop_ringing(lc); -#endif - stopStreams(); - CallSessionPrivate::abort(errorMsg); -} - void MediaSessionPrivate::accepted () { L_Q(MediaSession); CallSessionPrivate::accepted(); @@ -3636,6 +3628,14 @@ void MediaSessionPrivate::reportBandwidthForStream (MediaStream *ms, LinphoneStr // ----------------------------------------------------------------------------- +void MediaSessionPrivate::abort (const string &errorMsg) { +#if 0 + linphone_core_stop_ringing(lc); +#endif + stopStreams(); + CallSessionPrivate::abort(errorMsg); +} + void MediaSessionPrivate::handleIncomingReceivedStateInIncomingNotification () { L_Q(MediaSession); /* Try to be best-effort in giving real local or routable contact address for 100Rel case */ @@ -3660,6 +3660,38 @@ bool MediaSessionPrivate::isReadyForInvite () const { return callSessionReady && iceReady; } +LinphoneStatus MediaSessionPrivate::pause () { + L_Q(MediaSession); + if ((state != LinphoneCallStreamsRunning) && (state != LinphoneCallPausedByRemote)) { + lWarning() << "Cannot pause this MediaSession, it is not active"; + return -1; + } + string subject; + if (sal_media_description_has_dir(resultDesc, SalStreamSendRecv)) + subject = "Call on hold"; + else if (sal_media_description_has_dir(resultDesc, SalStreamRecvOnly)) + subject = "Call on hold for me too"; + else { + lError() << "No reason to pause this call, it is already paused or inactive"; + return -1; + } +#if 0 + call->broken = FALSE; +#endif + setState(LinphoneCallPausing, "Pausing call"); + makeLocalMediaDescription(); + sal_call_set_local_media_description(op, localDesc); + if (sal_call_update(op, subject.c_str(), false) != 0) + linphone_core_notify_display_warning(core, "Could not pause the call"); + if (listener) + listener->resetCurrentSession(*q); + linphone_core_notify_display_status(core, "Pausing the current call..."); + if (audioStream || videoStream || textStream) + stopStreams(); + pausedByApp = false; + return 0; +} + void MediaSessionPrivate::setTerminated () { freeResources(); CallSessionPrivate::setTerminated(); @@ -4127,6 +4159,61 @@ void MediaSession::iterate (time_t currentRealTime, bool oneSecondElapsed) { CallSession::iterate(currentRealTime, oneSecondElapsed); } +LinphoneStatus MediaSession::pause () { + L_D(MediaSession); + LinphoneStatus result = d->pause(); + if (result == 0) + d->pausedByApp = true; + return result; +} + +LinphoneStatus MediaSession::resume () { + L_D(MediaSession); + if (d->state != LinphoneCallPaused) { + lWarning() << "we cannot resume a call that has not been established and paused before"; + return -1; + } + if (!d->params->getPrivate()->getInConference()) { + if (linphone_core_sound_resources_locked(d->core)) { + lWarning() << "Cannot resume MediaSession " << this << " because another call is locking the sound resources"; + return -1; + } + linphone_core_preempt_sound_resources(d->core); + lInfo() << "Resuming MediaSession " << this; + } + d->automaticallyPaused = false; +#if 0 + call->broken = FALSE; +#endif + /* Stop playing music immediately. If remote side is a conference it + * prevents the participants to hear it while the 200OK comes back. */ + if (d->audioStream) + audio_stream_play(d->audioStream, nullptr); + d->makeLocalMediaDescription(); + if (!d->core->sip_conf.sdp_200_ack) + sal_call_set_local_media_description(d->op, d->localDesc); + else + sal_call_set_local_media_description(d->op, nullptr); + sal_media_description_set_dir(d->localDesc, SalStreamSendRecv); + string subject = "Call resuming"; + if (d->params->getPrivate()->getInConference() && !getCurrentParams()->getPrivate()->getInConference()) + subject = "Conference"; + if (sal_call_update(d->op, subject.c_str(), false) != 0) + return -1; + d->setState(LinphoneCallResuming,"Resuming"); + if (!d->params->getPrivate()->getInConference() && d->listener) + d->listener->setCurrentSession(*this); + ostringstream os; + os << "Resuming the call with " << getRemoteAddressAsString(); + linphone_core_notify_display_status(d->core, os.str().c_str()); + if (d->core->sip_conf.sdp_200_ack) { + /* We are NOT offering, set local media description after sending the call so that we are ready to + * process the remote offer when it will arrive. */ + sal_call_set_local_media_description(d->op, d->localDesc); + } + return 0; +} + void MediaSession::sendVfuRequest () { #ifdef VIDEO_ENABLED L_D(MediaSession); diff --git a/src/conference/session/media-session.h b/src/conference/session/media-session.h index 10ee36e5e..2d3d1ad10 100644 --- a/src/conference/session/media-session.h +++ b/src/conference/session/media-session.h @@ -46,6 +46,8 @@ public: void initiateIncoming (); bool initiateOutgoing (); void iterate (time_t currentRealTime, bool oneSecondElapsed); + LinphoneStatus pause (); + LinphoneStatus resume (); void sendVfuRequest (); void startIncomingNotification (); int startInvite (const Address *destination);