diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index f7caef81adef27a2e7ad7ec33f6aae49c3c694e1..2b5ec76a83f04f9c163d16312348b0ddeb0b881d 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -47,13 +47,19 @@ AudioRtp::~AudioRtp (void) {
 
 int 
 AudioRtp::createNewSession (SipCall *ca) {
+  ost::MutexLock m(_threadMutex);
   // Start RTP Send/Receive threads
   _symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false;
   _RTXThread = new AudioRtpRTX (ca, Manager::instance().getAudioDriver(), _symmetric);
 
-  //_debug("AudioRtp::createNewSession: starting RTX thread\n");
-  if (_RTXThread->start() != 0) {
-    return -1;
+  _debug("AudioRtp::createNewSession: starting RTX thread\n");
+  try {
+    if (_RTXThread->start() != 0) {
+//    if (_RTXThread->start() != 0) {
+      return -1;
+    }
+  } catch(...) {
+    _debug("exception on start?");
   }
   return 0;
 }
@@ -62,6 +68,8 @@ AudioRtp::createNewSession (SipCall *ca) {
 void
 AudioRtp::closeRtpSession () {
   // This will make RTP threads finish.
+  _debug("waiting start signal...\n");
+  _debug("receive start signal...");
   delete _RTXThread; _RTXThread = NULL;
 }
 
@@ -79,7 +87,7 @@ AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, AudioLayer* driver, bool sym) : _cod
   std::string localipConfig = _ca->getLocalIp();
   ost::InetHostAddress local_ip(localipConfig.c_str());
 
-  _debug("AudioRtpRTX ctor : Local IP:port %s:%d\tsymmetric:%d\n", local_ip.getHostname(), _ca->getLocalAudioPort(), _sym);
+  //_debug("AudioRtpRTX ctor : Local IP:port %s:%d\tsymmetric:%d\n", local_ip.getHostname(), _ca->getLocalAudioPort(), _sym);
 
   if (!_sym) {
     _sessionRecv = new ost::RTPSession(local_ip, _ca->getLocalAudioPort());
@@ -93,11 +101,15 @@ AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, AudioLayer* driver, bool sym) : _cod
 }
 
 AudioRtpRTX::~AudioRtpRTX () {
+  _start.wait();
+
   try {
-    terminate();
-  } catch (...) {
-    _debug("AudioRtpRTX: try to terminate, but catch an exception...\n");
+    this->terminate();
+  } catch(...) {
+    _debug("audiortprtx dtor catches an exception\n");
+    throw;
   }
+  //_debug("terminate audiortprtx ended...\n");
   _ca = NULL;
 
   if (!_sym) {
@@ -113,6 +125,8 @@ AudioRtpRTX::~AudioRtpRTX () {
 void
 AudioRtpRTX::initAudioRtpSession (void) 
 {
+  try {
+  //_debug("Init audio RTP session\n");
   ost::InetHostAddress remote_ip(_ca->getRemoteSdpAudioIp());
   if (!remote_ip) {
     _debug("RTP: Target IP address [%s] is not correct!\n", _ca->getRemoteSdpAudioIp());
@@ -148,8 +162,7 @@ AudioRtpRTX::initAudioRtpSession (void)
     _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) _ca->payload));
 
     _sessionSend->setMark(true);
-    setCancel(cancelImmediate);
-
+    //setCancel(cancelImmediate);
   } else {
 
     _debug("RTP(Send): Added session destination %s:%d\n", 
@@ -160,9 +173,13 @@ AudioRtpRTX::initAudioRtpSession (void)
     }
 
     _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) _ca->payload));
-    setCancel(cancelImmediate);
+    //setCancel(cancelImmediate);
   }
   _debug("== AudioRtpRTX::initAudioRtpSession end == \n");
+  } catch(...) {
+    _debug("initAudioRtpSession catch an exception\n");
+    throw;
+  }
 }
 
 void
@@ -190,7 +207,7 @@ AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_m
   }
   if ( bytesAvail != maxBytesToGet ) {
     // fill end with 0...
-    _debug("Padding mic: %d bytes\n", (maxBytesToGet-bytesAvail)/2);
+    //_debug("Padding mic: %d bytes\n", (maxBytesToGet-bytesAvail)/2);
     bzero(data_from_mic_mono + (bytesAvail/4), (maxBytesToGet-bytesAvail)/2);
   }
 
@@ -203,12 +220,15 @@ AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_m
       int compSize = ac->codecEncode (data_to_send, data_from_mic_mono, RTP_FRAMES2SEND*2);
       // encode divise by two
       // Send encoded audio sample over the network
+      //fprintf(stderr, "m");
       if (!_sym) {
         _sessionSend->putData(timestamp, data_to_send, compSize);
       } else {
         _session->putData(timestamp, data_to_send, compSize);
       }
-    } else { _debug("No AudioCodec for the mic\n"); }
+    } else { 
+      _debug("No AudioCodec for the mic\n"); 
+    }
   }
 }
 
@@ -253,6 +273,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers_stereo, int16* data
   // If the current call is the call which is answered
   // Set decoded data to sound device
   // expandedSize is in mono/bytes, since we double in stereo, we send two time more
+  //fprintf(stderr, "r");
   Manager::instance().getAudioDriver()->putMain(data_for_speakers_stereo, expandedSize*2);
   Manager::instance().getAudioDriver()->startStream();
 
@@ -269,7 +290,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers_stereo, int16* data
 }
 
 void
-AudioRtpRTX::run (void) {
+AudioRtpRTX::run () {
   //mic, we receive from soundcard in stereo, and we send encoded
   //encoding before sending
   int16 *data_from_mic_stereo = new int16[RTP_FRAMES2SEND*2];
@@ -281,53 +302,64 @@ AudioRtpRTX::run (void) {
   int16 *data_for_speakers_recv = new int16[RTP_FRAMES2SEND];
   int16 *data_for_speakers_stereo = new int16[RTP_FRAMES2SEND*2];
 
-  // Init the session
-  initAudioRtpSession();
-
-  // flush stream:
-  ManagerImpl& manager = Manager::instance();
-  AudioLayer *audiolayer = manager.getAudioDriver();
-
-  // start running the packet queue scheduler.
-  //_debug("Thread: start session of AudioRtpRTX\n");
-  if (!_sym) {
-    _sessionRecv->startRunning();
-    _sessionSend->startRunning();
-  } else {
-    _session->startRunning();
-    _debug("Session is now: %d active?\n", _session->isActive());
+  try {
+    _debug("Audio RtpRTX is running\n");
+
+    // Init the session
+    initAudioRtpSession();
+    _start.post();
+
+    // flush stream:
+    AudioLayer *audiolayer = Manager::instance().getAudioDriver();
+
+    // start running the packet queue scheduler.
+    _debug("Thread: start session of AudioRtpRTX\n");
+    if (!_sym) {
+      _sessionRecv->startRunning();
+      _sessionSend->startRunning();
+    } else {
+      _session->startRunning();
+      _debug("Session is now: %d active?\n", _session->isActive());
+    }
+  
+    int timestamp = 0; // for mic
+    int countTime = 0; // for receive
+    // TODO: get frameSize from user config 
+    int frameSize = 20; // 20ms frames
+    TimerPort::setTimer(frameSize);
+  
+    audiolayer->flushMic();
+    audiolayer->startStream();
+    while (!testCancel()) {
+      ////////////////////////////
+      // Send session
+      ////////////////////////////
+      sendSessionFromMic(char_to_send, data_from_mic_stereo, data_from_mic_mono, timestamp);
+      timestamp += RTP_FRAMES2SEND;
+
+      ////////////////////////////
+      // Recv session
+      ////////////////////////////
+      receiveSessionForSpkr(data_for_speakers_stereo, data_for_speakers_recv, countTime);
+
+      // Let's wait for the next transmit cycle
+      Thread::sleep(TimerPort::getTimer());
+      TimerPort::incTimer(frameSize); // 'frameSize' ms
+    }
+    //_debug("stop stream for audiortp loop\n");
+    audiolayer->stopStream();
+  } catch(std::exception &e) {
+    _debug("AudioRTP Thread, run function, has caught an exception here: %s\n", e.what());
+    throw;
+  } catch(...) {
+    _debug("AudioRTP Thread, run function, has caught an unknown exception here\n");
+    throw;
   }
-
-  int timestamp = 0; // for mic
-  int countTime = 0; // for receive
-  // TODO: get frameSize from user config 
-  int frameSize = 20; // 20ms frames
-  TimerPort::setTimer(frameSize);
-
-  audiolayer->flushMic();
-	while (!testCancel() && _ca != NULL) {
-		////////////////////////////
-		// Send session
-		////////////////////////////
-		sendSessionFromMic(char_to_send, data_from_mic_stereo, data_from_mic_mono, timestamp);
-		timestamp += RTP_FRAMES2SEND;
-
-		////////////////////////////
-		// Recv session
-		////////////////////////////
-    receiveSessionForSpkr(data_for_speakers_stereo, data_for_speakers_recv, countTime);
-		
-		// Let's wait for the next transmit cycle
-		Thread::sleep(TimerPort::getTimer());
-		TimerPort::incTimer(frameSize); // 'frameSize' ms
-	}
-  audiolayer->stopStream();
-
-	delete [] data_for_speakers_stereo; data_for_speakers_stereo = 0;
+  delete [] data_for_speakers_stereo; data_for_speakers_stereo = 0;
   delete [] data_for_speakers_recv;   data_for_speakers_recv   = 0;
-	delete [] char_to_send;          char_to_send          = 0;
-	delete [] data_from_mic_mono;    data_from_mic_mono    = 0;
-	delete [] data_from_mic_stereo;  data_from_mic_stereo  = 0;
+  delete [] char_to_send;          char_to_send          = 0;
+  delete [] data_from_mic_mono;    data_from_mic_mono    = 0;
+  delete [] data_from_mic_stereo;  data_from_mic_stereo  = 0;
 }
 
 
diff --git a/src/audio/audiortp.h b/src/audio/audiortp.h
index 615843881184d5ad02f58d6ffa4e3f9007ad49a7..338893ee730c0b9c13cc6cd304856bba307804e1 100644
--- a/src/audio/audiortp.h
+++ b/src/audio/audiortp.h
@@ -50,6 +50,7 @@ private:
 	ost::RTPSession *_sessionSend;
 	ost::RTPSession *_sessionRecv;
 	ost::SymmetricRTPSession *_session;
+  ost::Semaphore _start;
 	bool _sym;
 
   // build codec...
@@ -76,6 +77,7 @@ public:
 private:
 	AudioRtpRTX*	_RTXThread;
 	bool			_symmetric;
+  ost::Mutex _threadMutex;
 };
 
 #endif // __AUDIO_RTP_H__
diff --git a/src/gui/server/requestmanager.cpp b/src/gui/server/requestmanager.cpp
index f789a84b68e26a6d23160d6dc360e9fa9d281ec8..967e2e5486a11567bc6effc7447341af1e5e8951 100644
--- a/src/gui/server/requestmanager.cpp
+++ b/src/gui/server/requestmanager.cpp
@@ -76,7 +76,7 @@ RequestManager::exec()
       { // session mutex block
         _debug("Closing TCP Session... \n");
         _sessionMutex.enterMutex(); 
-	if (_sessionIO) _sessionIO->sendLast();
+        if (_sessionIO) _sessionIO->sendLast();
         delete _sessionIO; _sessionIO = NULL;
         _sessionMutex.leaveMutex();
         _debug("TCP Session has closed\n");
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 9f7374e643a54329f305d0069e47437541fa082f..7dd8f5f2bba60a1671302f606952d54552666f46 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -882,11 +882,9 @@ ManagerImpl::stopTone() {
   _debug("TONE: stop tone/stream...\n");
   getAudioDriver()->stopStream();
 
-  _debug("TONE: stop tone...\n");
   _toneMutex.enterMutex();
   _telephoneTone->setCurrentTone(Tone::TONE_NULL);
   _toneMutex.leaveMutex();
-  _debug("TONE: tone stopped\n");
 
   // for ringing tone..
   _toneMutex.enterMutex();
@@ -895,7 +893,6 @@ ManagerImpl::stopTone() {
     _tone->stopTone();
   }
   _toneMutex.leaveMutex();
-  _debug("TONE: leave stop tone function\n");
 }
 
 /**
diff --git a/src/sipcall.cpp b/src/sipcall.cpp
index e1636b118315a399f80c0c4dbe5d70d4504c39a5..1842ab783782b749b6e85247cc86dd1be9a944c7 100644
--- a/src/sipcall.cpp
+++ b/src/sipcall.cpp
@@ -49,6 +49,8 @@ SipCall::SipCall (CALLID id, CodecDescriptorVector* cdv) : _localIp("127.0.0.1")
   _remote_sdp_audio_port = 0;
   _local_sendrecv  = 0;           /* _SENDRECV, _SENDONLY, _RECVONLY */
   _remote_sendrecv = 0;
+
+  _reinvite = false;
 }
 
 
@@ -179,7 +181,10 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
       osip_from_t *from;
       osip_from_init(&from);
       osip_from_parse(from, _remote_uri);
-      _name = osip_from_get_displayname(from);
+      char *name = osip_from_get_displayname(from);
+      if ( name != NULL ) {
+        _name = name;
+      }
       osip_uri_t* url = osip_from_get_url(from); 
       if ( url != NULL ) {
         _number = url->username;
@@ -221,6 +226,7 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
   eXosip_lock();
   sdp_media_t *remote_med = eXosip_get_audio_media (remote_sdp);
   eXosip_unlock();
+
   if (remote_med == NULL || remote_med->m_port == NULL) {
     // no audio media proposed
     _debug("< Sending 415 Unsupported media type\n");
@@ -300,6 +306,166 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
   return 0;
 }
 
+// newReinviteCall is called when the IP-Phone user receives a change in the call
+// it's almost an newIncomingCall but we send a 200 OK
+// See: 3.7.  Session with re-INVITE (IP Address Change)
+int 
+SipCall::newReinviteCall (eXosip_event_t *event) {
+
+  _cid = event->cid;
+  _did = event->did;
+  _tid = event->tid;
+
+  if (_did < 1 && _cid < 1) {
+    return -1; /* not enough information for this event?? */
+  }
+  osip_strncpy (_textinfo, event->textinfo, 255);
+
+  if (event->response != NULL) {
+    _status_code = event->response->status_code;
+    snprintf (_reason_phrase, 49, "%s", event->response->reason_phrase);
+    _debug("  Status: %d %s\n", _status_code, _reason_phrase);
+  }
+
+  strcpy(_remote_uri, "");
+  _name = "";
+  _number = "";
+  if (event->request != NULL) {
+    char *tmp = NULL;
+
+    osip_from_to_str(event->request->from, &tmp);
+    if (tmp != NULL) {
+      snprintf (_remote_uri, 255, "%s", tmp);
+      osip_free (tmp);
+
+      // Get the name/number
+      osip_from_t *from;
+      osip_from_init(&from);
+      osip_from_parse(from, _remote_uri);
+      char *name = osip_from_get_displayname(from);
+      if ( name != NULL ) {
+        _name = name;
+      }
+      osip_uri_t* url = osip_from_get_url(from); 
+      if ( url != NULL ) {
+        _number = url->username;
+      }
+      osip_from_free(from);
+    }
+  }
+  _debug("  Name: %s\n", _name.c_str());
+  _debug("  Number: %s\n", _number.c_str());
+  _debug("  Remote URI: %s\n", _remote_uri);
+
+  /* negotiate payloads */
+  sdp_message_t *remote_sdp = NULL;
+  if (event->request != NULL) {
+    eXosip_lock();
+    remote_sdp = eXosip_get_sdp_info (event->request);
+    eXosip_unlock();
+  }
+  if (remote_sdp == NULL) {
+    _debug("SipCall::newIncomingCall: No remote SDP in REINVITE request. Sending 400 BAD REQUEST\n");
+    // Send 400 BAD REQUEST
+    eXosip_lock();
+    eXosip_call_send_answer (_tid, 400, NULL);
+    eXosip_unlock();
+    return 0;
+  }
+  /* TODO: else build an offer */
+
+  // Remote Media IP
+  eXosip_lock();
+  sdp_connection_t *conn = eXosip_get_audio_connection (remote_sdp);
+  eXosip_unlock();
+  if (conn != NULL && conn->c_addr != NULL) {
+      snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+      _debug("  Remote Audio IP: %s\n", _remote_sdp_audio_ip);
+  }
+
+  // Remote Media Port
+  eXosip_lock();
+  sdp_media_t *remote_med = eXosip_get_audio_media (remote_sdp);
+  eXosip_unlock();
+
+  if (remote_med == NULL || remote_med->m_port == NULL) {
+    // no audio media proposed
+    _debug("< Sending 415 Unsupported media type\n");
+    eXosip_lock();
+    eXosip_call_send_answer (_tid, 415, NULL);
+    eXosip_unlock();
+    sdp_message_free (remote_sdp);
+    return 0;
+  }
+  _remote_sdp_audio_port = atoi(remote_med->m_port);
+  _debug("  Remote Audio Port: %d\n", _remote_sdp_audio_port);
+
+  // Remote Payload
+  char *tmp = NULL;
+  if (_remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') {
+    int pos = 0;
+    while (!osip_list_eol (remote_med->m_payloads, pos)) {
+      tmp = (char *) osip_list_get (remote_med->m_payloads, pos);
+      if (tmp != NULL && ( 0 == osip_strcasecmp (tmp, "0") || 0 == osip_strcasecmp (tmp, "8") )) {
+        break;
+      }
+      tmp = NULL;
+      pos++;
+    }
+  }
+  if (tmp != NULL) {
+    payload = atoi (tmp);
+    _debug("  Payload: %d\n", payload);
+    setAudioCodec(_cdv->at(0)->alloc(payload, "")); // codec builder for the mic
+  } else {
+    _debug("< Sending 415 Unsupported media type\n");
+    eXosip_lock();
+    eXosip_call_send_answer (_tid, 415, NULL);
+    eXosip_unlock();
+    sdp_message_free (remote_sdp);
+    return 0;
+  }
+
+  osip_message_t *answer = 0;
+  eXosip_lock();
+  _debug("< Building Answer 200\n");
+  if (0 == eXosip_call_build_answer (_tid, 200, &answer)) {
+    if ( 0 != sdp_complete_message(remote_sdp, answer)) {
+      osip_message_free(answer);
+      // Send 415 Unsupported media type
+      eXosip_call_send_answer (_tid, 415, NULL);
+      _debug("< Sending Answer 415\n");
+    } else {
+
+      sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
+      sdp_media_t *local_med = NULL;
+      if (local_sdp != NULL) {
+         local_med = eXosip_get_audio_media(local_sdp);
+      }
+      if (local_sdp != NULL && local_med != NULL) {
+        /* search if stream is sendonly or recvonly */
+        _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
+        _local_sendrecv =  sdp_analyse_attribute (local_sdp, local_med);
+        _debug("  Remote SendRecv: %d\n", _remote_sendrecv);
+        _debug("  Local  SendRecv: %d\n", _local_sendrecv);
+        if (_local_sendrecv == _SENDRECV) {
+          if (_remote_sendrecv == _SENDONLY)      { _local_sendrecv = _RECVONLY; }
+          else if (_remote_sendrecv == _RECVONLY) { _local_sendrecv = _SENDONLY; }
+        }
+        _debug("  Final Local SendRecv: %d\n", _local_sendrecv);
+        sdp_message_free (local_sdp);
+      }
+      _debug("< Sending answer 200\n");
+      if (0 != eXosip_call_send_answer (_tid, 200, answer)) {
+        _debug("SipCall::newIncomingCall: cannot send 200 OK?\n");
+      }
+    }
+  }
+  eXosip_unlock ();
+  sdp_message_free (remote_sdp);
+  _reinvite = true;
+  return 0;
+}
 
 int 
 SipCall::ringingCall (eXosip_event_t *event) {     
@@ -343,61 +509,62 @@ SipCall::receivedAck (eXosip_event_t *event)
 
 int 
 SipCall::answeredCall(eXosip_event_t *event) {
-    _cid = event->cid;
-    _did = event->did;
+  _cid = event->cid;
+  _did = event->did;
 
   if (_did < 1 && _cid < 1)	{
     return -1; /* not enough information for this event?? */
   }
-	osip_strncpy(this->_textinfo,   event->textinfo, 255);
+  osip_strncpy(this->_textinfo,   event->textinfo, 255);
 
-  	if (event->response != NULL) {
-  		_status_code = event->response->status_code;
-    	snprintf (_reason_phrase, 49, "%s", event->response->reason_phrase);
-  	}
+  if (event->response != NULL) {
+    _status_code = event->response->status_code;
+    snprintf (_reason_phrase, 49, "%s", event->response->reason_phrase);
 
-  	if (event->request != NULL) {
-      	char *tmp = NULL;
+    char *tmp = NULL;
 
-      	osip_from_to_str (event->request->from, &tmp);
-      	if (tmp != NULL) {
-          	snprintf (_remote_uri, 255, "%s", tmp);
-          	osip_free (tmp);
-       	}
+    osip_from_to_str (event->response->from, &tmp);
+    if (tmp != NULL) {
+        snprintf (_remote_uri, 255, "%s", tmp);
+        osip_free (tmp);
     }
-	
-  	eXosip_lock ();
-  	{
+  }
+  _debug("  Status: %d %s\n", _status_code, _reason_phrase);
+  _debug("  From URI: %s\n", _remote_uri);
+
+  eXosip_lock ();
+  {
     osip_message_t *ack = NULL;
     int i;
 
     i = eXosip_call_build_ack (_did, &ack);
     if (i != 0) {
-    	_debug("SipCall::answeredCall: Cannot build ACK for call!\n");
+      _debug("SipCall::answeredCall: Cannot build ACK for call!\n");
     } else {
-        sdp_message_t *local_sdp = NULL;
-        sdp_message_t *remote_sdp = NULL;
+      sdp_message_t *local_sdp = NULL;
+      sdp_message_t *remote_sdp = NULL;
 
-        if (event->request != NULL && event->response != NULL) {
-            local_sdp = eXosip_get_sdp_info (event->request);
-            remote_sdp = eXosip_get_sdp_info (event->response);
-        }
-        if (local_sdp == NULL && remote_sdp != NULL) {
-            /* sdp in ACK */
-            i = sdp_complete_message (remote_sdp, ack);
-            if (i != 0) {
-                _debug("SipCall::answeredCall: Cannot complete ACK with sdp body?!\n");
-            }
+      if (event->request != NULL && event->response != NULL) {
+        local_sdp = eXosip_get_sdp_info (event->request);
+        remote_sdp = eXosip_get_sdp_info (event->response);
+      }
+      if (local_sdp == NULL && remote_sdp != NULL) {
+        /* sdp in ACK */
+        i = sdp_complete_message (remote_sdp, ack);
+        if (i != 0) {
+            _debug("SipCall::answeredCall: Cannot complete ACK with sdp body?!\n");
         }
-        sdp_message_free (local_sdp);
-        sdp_message_free (remote_sdp);
+      }
+      sdp_message_free (local_sdp);
+      sdp_message_free (remote_sdp);
 
-        eXosip_call_send_ack (_did, ack);
-   	}
-   }
-  	eXosip_unlock ();
+      _debug("< Send ACK\n");
+      eXosip_call_send_ack (_did, ack);
+    }
+  }
+  eXosip_unlock ();
 
-	return 0;
+  return 0;
 }
 
 void
@@ -440,6 +607,7 @@ SipCall::answeredCall_without_hold (eXosip_event_t *event)
         _remote_sdp_audio_port = atoi (remote_med->m_port);
       }
       eXosip_unlock();
+      _debug("  Remote Audio: %s:%d\n", _remote_sdp_audio_ip, _remote_sdp_audio_port);
 
       if (_remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0' && 
         remote_med != NULL) {
@@ -448,10 +616,10 @@ SipCall::answeredCall_without_hold (eXosip_event_t *event)
 
       if (tmp != NULL) {
         payload = atoi (tmp);
-        _debug("SipCall::answeredCall_without_hold: For outgoing call: ca->payload = %d\n", payload);
         setAudioCodec(_cdv->at(0)->alloc(payload, ""));
       }
     }
+    _debug("  Remote Payload: %d\n", payload);
 
     if (local_sdp == NULL) {
       _debug("SipCall::answeredCall_without_hold: SDP body was probably in the ACK (TODO)\n");
@@ -465,6 +633,7 @@ SipCall::answeredCall_without_hold (eXosip_event_t *event)
       if (local_med != NULL && local_med->m_port != NULL) {
         audio_port = atoi (local_med->m_port);
       }
+      _debug("  Local Audio port: %d\n", audio_port);
 
       if (tmp != NULL && audio_port > 0
           && _remote_sdp_audio_port > 0
@@ -480,6 +649,8 @@ SipCall::answeredCall_without_hold (eXosip_event_t *event)
               _local_sendrecv = _SENDONLY;
         }
       }
+      _debug("  Remote Sendrecv: %d\n", _remote_sendrecv);
+      _debug("  Local Sendrecv: %d\n", _local_sendrecv);
     }
     sdp_message_free (local_sdp);
     sdp_message_free (remote_sdp);
diff --git a/src/sipcall.h b/src/sipcall.h
index bbeea534a273cd28cf3abdc38afb8a291ab63274..266d4b53393acf29879769e9f27653764d9a6a2e 100644
--- a/src/sipcall.h
+++ b/src/sipcall.h
@@ -44,11 +44,12 @@ public:
 	~SipCall (void);
 
   int payload;
-	
-	/*
-	 * Store information about incoming call and negociate payload
-	 */
-	int newIncomingCall 	(eXosip_event_t *);
+
+  /**
+   * Store information about incoming call and negociate payload
+   */
+  int newIncomingCall(eXosip_event_t *);
+  int newReinviteCall(eXosip_event_t *);
 	
 	/*
 	 * Use to answer to a ONHOLD/OFFHOLD event 
@@ -72,6 +73,9 @@ public:
   std::string getLocalIp() { return _localIp; }
   void setLocalIp(const std::string& ip) { _localIp = ip; }
 
+  bool isReinvite() { return _reinvite; }
+  void endReinvite() { _reinvite = false; }; 
+
 	/*
 	 * Manage id, did (dialog-id), cid (call-id) and tid (transaction-id) 
 	 * for each sipcall
@@ -147,6 +151,8 @@ private:
   std::string _localIp;
   std::string _name;   // set by incoming call
   std::string _number; // set by incoming call
+
+  bool _reinvite;
 };
 
 #endif // __SIP_CALL_H__
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index af4c86cd649342d34fe5ff4e0c0c7bd15aa08c2c..45643a385d7b9931cb138cb34975020149d2f6c9 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -93,9 +93,12 @@ SipVoIPLink::init(void)
     if (i != 0) {
       _debug("Could not initialize transport layer\n");
       return -1;
+    } else {
+      _debug("VoIP Link listen on random port %d\n", RANDOM_SIP_PORT);
     }
+  } else {
+   _debug("VoIP Link listen on port %d\n", DEFAULT_SIP_PORT);
   }
-
   // If use STUN server, firewall address setup
   if (Manager::instance().useStun()) {
     eXosip_set_user_agent(tmp.data());
@@ -217,12 +220,12 @@ SipVoIPLink::setRegister (void)
 
   int i = eXosip_register_send_register (_reg_id, reg);
   if (i == -2) {
-    _debug("cannot build registration, check the setup\n"); 
+    _debug("Cannot build registration, check the setup\n"); 
     eXosip_unlock();
     return -1;
   }
   if (i == -1) {
-    _debug("Registration Failed\n");
+    _debug("Registration sending failed\n");
     eXosip_unlock();
     return -1;
   }
@@ -378,6 +381,7 @@ SipVoIPLink::answer (CALLID id)
   eXosip_unlock();
 
   // Incoming call is answered, start the sound channel.
+  _debug("Starting AudioRTP\n");
   if (_audiortp.createNewSession (getSipCall(id)) < 0) {
     _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__);
     i = -1;
@@ -403,6 +407,7 @@ SipVoIPLink::hangup (CALLID id)
   eXosip_unlock();
 
   // Release RTP channels
+  _debug("Stopping AudioRTP\n");
   _audiortp.closeRtpSession();
 
   deleteSipCall(id);
@@ -483,6 +488,7 @@ SipVoIPLink::onhold (CALLID id)
   }
   
   // Send request
+  _debug("Stopping AudioRTP\n");
   _audiortp.closeRtpSession();
 
   eXosip_lock ();
@@ -552,10 +558,11 @@ SipVoIPLink::offhold (CALLID id)
   eXosip_unlock ();
   
   // Enable audio
-    if (_audiortp.createNewSession (getSipCall(id)) < 0) {
-      _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__);
-      i = -1;
-    }
+  _debug("Stopping AudioRTP\n");
+  if (_audiortp.createNewSession (getSipCall(id)) < 0) {
+    _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__);
+    i = -1;
+  }
   return i;
 }
 
@@ -659,22 +666,23 @@ SipVoIPLink::getEvent (void)
     break;
 
   case EXOSIP_CALL_REINVITE:
-    _debug("!!! EXOSIP_CALL_REINVITE: Should reinvite? !!!\n");
+    _debug("> INVITE (reinvite)\n");
     //eXosip_call_send_answer(event->tid, 403, NULL);
     //488 as http://www.atosc.org/pipermail/public/osip/2005-June/005385.html
+
     id = findCallId(event);
     if (id != 0) {
       sipcall = getSipCall(id);
-      if (sipcall != NULL) {
-        _debug("Call reinvite : [id = %d, cid = %d, did = %d], localport=%d\n", id, event->cid, event->did,sipcall->getLocalAudioPort());
+      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();
-        sipcall->newIncomingCall(event);
-        if(!Manager::instance().callIsOnHold(id)) {
-          _audiortp.createNewSession(sipcall);
-        }
+        sipcall->newReinviteCall(event);
+        // we should receive an ack after that...
       }
     } else {
+      _debug("< Send 488 Not Acceptable Here");
       eXosip_lock();
       eXosip_call_send_answer(event->tid, 488, NULL);
       eXosip_unlock();
@@ -687,7 +695,7 @@ SipVoIPLink::getEvent (void)
 
   case EXOSIP_CALL_RINGING: // 9 peer call is ringing
     id = findCallIdInitial(event);
-    _debug("Call is ringing [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);
+    _debug("> Receive Call Ringing [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);
     if (id != 0) {
       getSipCall(id)->ringingCall(event);
       Manager::instance().peerRingingCall(id);
@@ -702,60 +710,69 @@ SipVoIPLink::getEvent (void)
     id = findCallIdInitial(event);
     if ( id != 0) {
       sipcall = getSipCall(id);
-      if ( sipcall ) {
-       _debug("Call is answered [id = %d, cid = %d, did = %d], localport=%d\n", 
-      id, event->cid, event->did,sipcall->getLocalAudioPort());
-      }
-
-      // Answer
-      if (Manager::instance().callCanBeAnswered(id)) {
-        sipcall->setStandBy(false);
-        _debug("Answering call first time\n");
-        if (sipcall->answeredCall(event) != -1) {
-          sipcall->answeredCall_without_hold(event);
-          Manager::instance().peerAnsweredCall(id);
-
-          if(!Manager::instance().callIsOnHold(id)) {
-            // Outgoing call is answered, start the sound channel.
-            _debug("Starting AudioRTP\n");
-            if (_audiortp.createNewSession (sipcall) < 0) {
-              _debug("FATAL: Unable to start sound (%s:%d)\n", 
-              __FILE__, __LINE__);
-              returnValue = -1;
-              break;
+      if ( sipcall != 0 ) {
+        _debug("> Receive Call Answer [id = %d, cid = %d, did = %d], localport=%d\n", id, event->cid, event->did, sipcall->getLocalAudioPort());
+
+        // Answer
+        if (Manager::instance().callCanBeAnswered(id)) {
+          sipcall->setStandBy(false);
+          if (sipcall->answeredCall(event) != -1) {
+            sipcall->answeredCall_without_hold(event);
+            Manager::instance().peerAnsweredCall(id);
+  
+            if(!Manager::instance().callIsOnHold(id)) {
+              // Outgoing call is answered, start the sound channel.
+              _debug("Starting AudioRTP\n");
+              if (_audiortp.createNewSession (sipcall) < 0) {
+                _debug("FATAL: Unable to start sound (%s:%d)\n", 
+                __FILE__, __LINE__);
+                returnValue = -1;
+                break;
+              }
             }
           }
+        } else {
+          // Answer to on/off hold to send ACK
+          _debug("Answering call\n");
+          sipcall->answeredCall(event);
         }
-      } else {
-        // Answer to on/off hold to send ACK
-        _debug("Answering call\n");
-        sipcall->answeredCall(event);
       }
       break;
     } else {
       returnValue = -1;
     }
   }
-  case EXOSIP_CALL_REDIRECTED:
+  case EXOSIP_CALL_REDIRECTED: // 11
     break;
 
-  case EXOSIP_CALL_ACK:
+  case EXOSIP_CALL_ACK: // 15
     id = findCallId(event);
-    _debug("ACK received [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);
-    if (id != 0) {
-      getSipCall(id)->receivedAck(event);
+    _debug("> Receive ACK [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);
+    if (id != 0 ) {
+      sipcall = getSipCall(id);
+      if(sipcall != 0 ) { 
+        sipcall->receivedAck(event);
+        if (sipcall->isReinvite()) {
+          sipcall->endReinvite();
+          if(!Manager::instance().callIsOnHold(id)) {
+            _debug("Starting AudioRTP\n");
+            _audiortp.createNewSession(sipcall);
+          }
+        }
+      }
     } else {
       returnValue = -1;
     }
     break;
 
     // The peer-user closed the phone call(we received BYE).
-  case EXOSIP_CALL_CLOSED:
+  case EXOSIP_CALL_CLOSED: // 25
     id = findCallId(event);
-    _debug("Call is closed [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);	
+    _debug("> BYE [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);	
     if (id != 0) {
       if (Manager::instance().callCanBeClosed(id)) {
          sipcall = getSipCall(id);
+         _debug("Stopping AudioRTP\n");
          _audiortp.closeRtpSession();
       }
       Manager::instance().peerHungupCall(id);
@@ -765,6 +782,9 @@ SipVoIPLink::getEvent (void)
     }	
     break;
   case EXOSIP_CALL_RELEASED:
+    if (event) {
+      _debug("SIP call released: [cid = %d, did = %d]\n", event->cid, event->did);
+    }
     //id = findCallId(event);
     //if (id!=0) {
     //Manager::instance().peerHungupCall(id);
@@ -851,7 +871,7 @@ SipVoIPLink::getEvent (void)
     //Manager::instance().displayError("getEvent : Registration Failure");
     break;
 
-  case EXOSIP_MESSAGE_NEW:
+  case EXOSIP_MESSAGE_NEW: //27
     unsigned int k;
 				
     if (event->request != NULL && MSG_IS_OPTIONS(event->request)) {
@@ -877,6 +897,7 @@ SipVoIPLink::getEvent (void)
 
     // Voice message 
     else if (event->request != NULL && MSG_IS_NOTIFY(event->request)){
+      _debug("> NOTIFY Voice message\n");
       int ii;
       unsigned int pos;
       unsigned int pos_slash;
@@ -1027,6 +1048,7 @@ SipVoIPLink::endSipCalls()
       eXosip_unlock();
 
       // Release RTP channels
+      _debug("Stopping AudioRTP\n");
       _audiortp.closeRtpSession();
       delete *iter; *iter = NULL;
     }
@@ -1308,20 +1330,18 @@ int
 SipVoIPLink::setAuthentication (void) 
 {
   ManagerImpl& manager = Manager::instance();
-  std::string login, pass, realm;
-  login = manager.getConfigString(SIGNALISATION, AUTH_USER_NAME);
+  std::string login = manager.getConfigString(SIGNALISATION, AUTH_USER_NAME);
   if (login.empty()) {
     login = manager.getConfigString(SIGNALISATION, USER_PART);
   }
-  pass = manager.getConfigString(SIGNALISATION, PASSWORD);
+  std::string pass = manager.getConfigString(SIGNALISATION, PASSWORD);
   if (pass.empty()) {
     manager.displayConfigError("Fill password field");
     return -1;
   }
   int returnValue = 0;
   eXosip_lock();
-  if (eXosip_add_authentication_info(login.data(), login.data(), 
-				     pass.data(), NULL, NULL) != 0) {
+  if (eXosip_add_authentication_info(login.data(), login.data(), pass.data(), NULL, NULL) != 0) {
     returnValue = -1;
   }
   eXosip_unlock();
@@ -1368,12 +1388,12 @@ SipVoIPLink::startCall (CALLID id, const std::string& from, const std::string& t
   if (!Manager::instance().useStun()) {
     // Set random port for outgoing call if no firewall
     setLocalPort(RANDOM_LOCAL_PORT);
-    _debug("SipVoIPLink::startCall: Local audio port: %d\n",_localPort);
+    _debug("  Setting local port to random: %d\n",_localPort);
   } else {
     // If use Stun server
     if (behindNat() != 0) {
-      _debug("SipVoIPLink::startCall: sip invite: firewall port = %d\n",Manager::instance().getFirewallPort());	
       setLocalPort(Manager::instance().getFirewallPort());
+      _debug("  Setting local port to firewall port: %d\n", _localPort);	
     } else {
       return -1;
     }