diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 70f3420b75906bebe023d185391ab527d8ef8886..519e23c0da15047d1830d456e21b41c2c94121fd 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -400,68 +400,70 @@ bool ManagerImpl::answerCall (const CallID& call_id) } //THREAD=Main -bool ManagerImpl::hangupCall (const CallID& call_id) +bool ManagerImpl::hangupCall (const CallID& callId) { + bool returnValue = true; - _info ("Manager: Hangup call %s", call_id.c_str()); + // First stop audio layer if there is no call anymore + int nbCalls = getCallList().size(); + if(nbCalls <= 0) { + AudioLayer *audiolayer = getAudioDriver(); - AccountID account_id; - bool returnValue = true; + if(audiolayer == NULL) { + _error("Manager: Error: Audio layer was not instantiated"); + return returnValue; + } + + _debug ("Manager: stop audio stream, there is no call remaining", nbCalls); + audiolayer->stopStream(); + } + + + if (_dbus == NULL) { + _error("Manager: Error: Dbus layer have not been instantiated"); + return false; + } + + if(!isValidCall(callId)) { + // We may still want to tell the client to hangup this call... + _dbus->getCallManager()->callStateChanged (callId, "HUNGUP"); + return returnValue; + } + + _info ("Manager: Hangup call %s", callId.c_str()); // store the current call id - CallID current_call_id = getCurrentCallId(); + CallID currentCallId = getCurrentCallId(); stopTone(); /* Broadcast a signal over DBus */ - _debug ("Manager: Send DBUS call state change (HUNGUP) for id %s", call_id.c_str()); - - if (_dbus) - _dbus->getCallManager()->callStateChanged (call_id, "HUNGUP"); + _debug ("Manager: Send DBUS call state change (HUNGUP) for id %s", callId.c_str()); - if (participToConference (call_id)) { - - Conference *conf = getConferenceFromCallID (call_id); + _dbus->getCallManager()->callStateChanged (callId, "HUNGUP"); + if (participToConference (callId)) { + Conference *conf = getConferenceFromCallID (callId); if (conf != NULL) { // remove this participant - removeParticipant (call_id); - - processRemainingParticipant (current_call_id, conf); + removeParticipant (callId); + processRemainingParticipant (currentCallId, conf); } - } else { // we are not participating to a conference, current call switched to "" - if (!isConference (current_call_id)) + if (!isConference (currentCallId)) { switchCall (""); + } } - /* Direct IP to IP call */ - if (getConfigFromCall (call_id) == Call::IPtoIP) { - returnValue = SIPVoIPLink::instance (AccountNULL)->hangup (call_id); + if (getConfigFromCall (callId) == Call::IPtoIP) { + /* Direct IP to IP call */ + returnValue = SIPVoIPLink::instance (AccountNULL)->hangup (callId); } - /* Classic call, attached to an account */ else { - account_id = getAccountFromCall (call_id); - -// // Account may be NULL if call have not been sent yet -// if (account_id == AccountNULL) { -// _error ("Manager: Error: account id is NULL in hangup"); -// returnValue = false; -// } else { - returnValue = getAccountLink (account_id)->hangup (call_id); - removeCallAccount (call_id); -// } - } - - int nbCalls = getCallList().size(); - - AudioLayer *audiolayer = getAudioDriver(); - - // stop streams - if (audiolayer && (nbCalls <= 0)) { - _debug ("Manager: stop audio stream, ther is only %d call(s) remaining", nbCalls); - audiolayer->stopStream(); + AccountID accountId = getAccountFromCall (callId); + returnValue = getAccountLink (accountId)->hangup (callId); + removeCallAccount (callId); } return returnValue; @@ -3704,6 +3706,20 @@ bool ManagerImpl::removeCallAccount (const CallID& callID) return false; } +bool ManagerImpl::isValidCall(const CallID& callID) +{ + ost::MutexLock m(_callAccountMapMutex); + CallAccountMap::iterator iter = _callAccountMap.find (callID); + + if(iter != _callAccountMap.end()) { + return true; + } + else { + return false; + } + +} + CallID ManagerImpl::getNewCallID () { std::ostringstream random_id ("s"); diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index bf07603925537dacd31dcec284dbded3c661827b..162d7f46703e39fbd8c587006bfdc789b22fa4e2 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -212,6 +212,7 @@ class ManagerImpl * Functions which occur with a user's action * Hangup the call * @param id The call identifier + * @return true on success */ bool hangupCall (const CallID& id); @@ -1331,6 +1332,14 @@ class ManagerImpl */ bool removeCallAccount (const CallID& callID); + /** + * Test if call is a valid call, i.e. have been created and stored in + * call-account map + * @param callID the CallID to be tested + * @return true if call is created and present in the call-account map + */ + bool isValidCall(const CallID& callID); + /** * Return a pointer to the instance of the mainbuffer */