From 897f34d9ce4643a85ed8a112710e70cd94a75726 Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Tue, 1 Nov 2005 20:17:54 +0000
Subject: [PATCH] Only switch call when no one are selected

---
 src/audio/audiortp.cpp | 13 ++++++++++---
 src/managerimpl.cpp    | 34 +++++++++++++++++++++++-----------
 src/managerimpl.h      |  2 ++
 src/sipvoiplink.cpp    | 20 ++++++++++++--------
 4 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index 2b5ec76a83..39c24ab7db 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -38,16 +38,23 @@
 // AudioRtp                                                          
 ////////////////////////////////////////////////////////////////////////////////
 AudioRtp::AudioRtp () {
-	_RTXThread = NULL;
+	_RTXThread = 0;
 }
 
 AudioRtp::~AudioRtp (void) {
-	delete _RTXThread; _RTXThread = NULL;
+	delete _RTXThread; _RTXThread = 0;
 }
 
 int 
 AudioRtp::createNewSession (SipCall *ca) {
   ost::MutexLock m(_threadMutex);
+
+  // something should stop the thread before...
+  if ( _RTXThread != 0 ) { 
+    _debug("AudioRTP error: try to create a new audio rtp thread...\n");
+    return -1; 
+  }
+
   // Start RTP Send/Receive threads
   _symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false;
   _RTXThread = new AudioRtpRTX (ca, Manager::instance().getAudioDriver(), _symmetric);
@@ -70,7 +77,7 @@ AudioRtp::closeRtpSession () {
   // This will make RTP threads finish.
   _debug("waiting start signal...\n");
   _debug("receive start signal...");
-  delete _RTXThread; _RTXThread = NULL;
+  delete _RTXThread; _RTXThread = 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index c8cee61164..b8aaa4bc01 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -209,6 +209,7 @@ ManagerImpl::pushBackNewCall (CALLID id, enum CallType type)
 Call*
 ManagerImpl::getCall (CALLID id)
 {
+  _debug("CALL: Getting call %d\n", id);
   Call* call = NULL;
   unsigned int size = _callVector.size();
   for (unsigned int i = 0; i < size; i++) {
@@ -228,6 +229,7 @@ ManagerImpl::getCall (CALLID id)
 void
 ManagerImpl::deleteCall (CALLID id)
 {
+  _debug("CALL: Deleting call %d\n", id);
   CallVector::iterator iter = _callVector.begin();
   while(iter!=_callVector.end()) {
     Call *call = *iter;
@@ -244,6 +246,13 @@ ManagerImpl::deleteCall (CALLID id)
   }
 }
 
+void
+ManagerImpl::setCurrentCallId(CALLID id)
+{
+  _debug("CALL: Setting current callid %d to %d\n", _currentCallId, id);
+  _currentCallId = id;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Management of events' IP-phone user
 ///////////////////////////////////////////////////////////////////////////////
@@ -255,7 +264,6 @@ ManagerImpl::outgoingCall (const std::string& to)
 {	
   CALLID id = generateNewCallId();
   Call *call = pushBackNewCall(id, Outgoing);
-  _debug("Outgoing Call with identifiant %d\n", id);
   ost::MutexLock m(_mutex);
   call->setState(Call::Progressing);
   call->setCallerIdNumber(to);
@@ -326,8 +334,10 @@ ManagerImpl::answerCall (CALLID id)
     decWaitingCall();
     call->setFlagNotAnswered(false);
   }
-  switchCall(id);
-  stopTone(); // before answer, don't stop the audio stream after open it...
+  if (call->getState() != Call::OnHold) {
+    switchCall(id);
+  }
+  stopTone(); // before answer, don't stop the audio stream after open it
   return call->answer();
 }
 
@@ -347,7 +357,7 @@ ManagerImpl::onHoldCall (CALLID id)
   if ( call->getState() == Call::OnHold || call->isNotAnswered()) {
     return 1;
   }
-  _currentCallId = 0;
+  setCurrentCallId(0);
   return call->onHold();
 }
 
@@ -367,7 +377,8 @@ ManagerImpl::offHoldCall (CALLID id)
   if (call->getState() == Call::OffHold) {
     return 1;
   }
-  _currentCallId = id;
+  _debug("CALL: setting current id = %d\n", id);
+  setCurrentCallId(id);
   int returnValue = call->offHold();
   // start audio if it's ok
   if (returnValue != -1) {
@@ -388,7 +399,7 @@ ManagerImpl::transferCall (CALLID id, const std::string& to)
   if (call == 0) {
     return -1;
   }
-  _currentCallId = 0;
+  setCurrentCallId(0);
   return call->transfer(to);
 }
 
@@ -431,7 +442,7 @@ ManagerImpl::refuseCall (CALLID id)
   }
   int refuse = call->refuse();
 
-  _currentCallId = 0;
+  setCurrentCallId(0);
   deleteCall(id);
   stopTone();
   return refuse;
@@ -780,7 +791,7 @@ ManagerImpl::peerHungupCall (CALLID id)
   deleteCall(id);
   call->setState(Call::Hungup);
 
-  _currentCallId = 0;
+  setCurrentCallId(0);
   return 1;
 }
 
@@ -1580,10 +1591,11 @@ ManagerImpl::getDirListing(const std::string& sequenceId, const std::string& pat
 void 
 ManagerImpl::switchCall(CALLID id)
 {
-  if (_currentCallId!=0 && id!=_currentCallId) {
-    //onHoldCall(_currentCallId); <-- this function block _mutex...
+  // we can only switch the current call id if we 
+  // it's not selected yet..
+  if (_currentCallId == 0 ) {
+    setCurrentCallId(id);
   }
-  _currentCallId = id;
 }
 
 
diff --git a/src/managerimpl.h b/src/managerimpl.h
index cf885e066a..f986eddc35 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -290,9 +290,11 @@ private:
 
   /*
    * Erase the Call(id) from the CallVector
+   * Protected by other function by _mutex lock
    */
   void deleteCall	(CALLID id);
   Call* getCall (CALLID id);
+  void setCurrentCallId(CALLID id);
 
   /*
    * Play one tone
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index 0471f0344c..75a8fe4c26 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -409,7 +409,9 @@ SipVoIPLink::hangup (CALLID id)
 
   // Release RTP channels
   _debug("Stopping AudioRTP\n");
-  _audiortp.closeRtpSession();
+  if (id == Manager::instance().getCurrentCallId()) {
+    _audiortp.closeRtpSession();
+  }
 
   deleteSipCall(id);
   return i;
@@ -684,8 +686,10 @@ SipVoIPLink::getEvent (void)
       if (sipcall != 0) {
         _debug("  Info [id = %d, cid = %d, did = %d], localport=%d\n", id, event->cid, event->did,sipcall->getLocalAudioPort());
 
-        _debug("Stopping AudioRTP\n");
-        _audiortp.closeRtpSession();
+        if ( id == Manager::instance().getCurrentCallId() ) {
+          _debug("Stopping AudioRTP\n");
+          _audiortp.closeRtpSession();
+        }
         sipcall->newReinviteCall(event);
         // we should receive an ack after that...
       }
@@ -728,14 +732,13 @@ SipVoIPLink::getEvent (void)
             sipcall->answeredCall_without_hold(event);
             Manager::instance().peerAnsweredCall(id);
   
-            if(!Manager::instance().callIsOnHold(id)) {
+            if(!Manager::instance().callIsOnHold(id) && Manager::instance().getCurrentCallId()==id) {
               // Outgoing call is answered, start the sound channel.
               _debug("Starting AudioRTP\n");
-              if (_audiortp.createNewSession (sipcall) < 0) {
+              if (_audiortp.createNewSession(sipcall) < 0) {
                 _debug("FATAL: Unable to start sound (%s:%d)\n", 
                 __FILE__, __LINE__);
                 returnValue = -1;
-                break;
               }
             }
           }
@@ -745,11 +748,11 @@ SipVoIPLink::getEvent (void)
           sipcall->answeredCall(event);
         }
       }
-      break;
     } else {
       returnValue = -1;
     }
   }
+   break;
   case EXOSIP_CALL_REDIRECTED: // 11
     break;
 
@@ -762,7 +765,7 @@ SipVoIPLink::getEvent (void)
         sipcall->receivedAck(event);
         if (sipcall->isReinvite()) {
           sipcall->endReinvite();
-          if(!Manager::instance().callIsOnHold(id)) {
+          if(!Manager::instance().callIsOnHold(id) && Manager::instance().getCurrentCallId()==id) {
             _debug("Starting AudioRTP\n");
             _audiortp.createNewSession(sipcall);
           }
@@ -1502,6 +1505,7 @@ SipVoIPLink::startCall (CALLID id, const std::string& from, const std::string& t
   }
   
   // this is the cid (call id from exosip)
+  _debug("< INVITE (%d)", id);
   int cid = eXosip_call_send_initial_invite (invite);
 
   _debug("> Start a new Call: Send INVITE\n");
-- 
GitLab