diff --git a/ChangeLog b/ChangeLog
index 6a49b5bae99a4a4c8f9ceb4de6e9c8d8e7aee99f..49d5fd6420f8fa64e22d34ff0ebcb6e687da0247 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Laurielle LEA (27 July 2005) version 0.4
+- Migrate from libeXoSIP 0.9.0 to libeXosip2-1.9.1-pre15 
+(http://www.antisip.com/download/)
+
 Laurielle LEA (21 July 2005) version 0.4
 - Change README.
 
diff --git a/DEPS b/DEPS
index d1f4c99b5cf5983d5c1f8044e2f1893dd034cab7..e924e675273db15a1e6a888060a69e2d03f010b6 100644
--- a/DEPS
+++ b/DEPS
@@ -1,5 +1,5 @@
 PortAudio: http://portaudio.com/archives/pa_snapshot_v19.tar.gz
 Common C++ 2 1.3.6: http://sourceforge.net/projects/cplusplus/
 ccRTP 1.3.0: http://sourceforge.net/projects/cplusplus/
-libosip 2.2.0: http://savannah.gnu.org/projects/osip/
-libeXoSIP 0.9.0: http://savannah.nongnu.org/projects/exosip/
+libosip 2.2.1: http://savannah.gnu.org/projects/osip/
+libeXosip2-1.9.1-pre14: http://www.antisip.com/download/
diff --git a/config.h.in b/config.h.in
index 35f2516284c6792300322b539bec03d3de744ae5..af06bd0e0a6d50960f55781f1e29427775e75048 100644
--- a/config.h.in
+++ b/config.h.in
@@ -15,8 +15,8 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
-/* Define to 1 if you have the <eXosip/eXosip.h> header file. */
-#undef HAVE_EXOSIP_EXOSIP_H
+/* Define to 1 if you have the <eXosip2/eXosip.h> header file. */
+#undef HAVE_EXOSIP2_EXOSIP_H
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
diff --git a/configure.ac b/configure.ac
index 741fd3d5da43cb114984e12eec201dc80ee0022a..a2556030f891c215e1bbd7d08fc648205323f4c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,7 +54,7 @@ dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS( \
 ostream \
-eXosip/eXosip.h \
+eXosip2/eXosip.h \
 portaudio.h \
 )
 
@@ -78,11 +78,11 @@ PKG_CHECK_MODULES(libosip2, libosip2 >= ${LIBOSIP2_MIN_VERSION})
 SFLPHONE_CXXFLAGS="$SFLPHONE_CXXFLAGS $libosip2_CFLAGS"
 SFLPHONE_LIBS="$SFLPHONE_LIBS $libosip2_LIBS"
 
-if test $ac_cv_header_eXosip_eXosip_h = no; then
-   AC_MSG_ERROR([*** missing eXipsip/eXosip.h. You need a working eXosip installation. See http://savannah.nongnu.org/projects/exosip/])
+if test $ac_cv_header_eXosip2_eXosip_h = no; then
+   AC_MSG_ERROR([*** missing eXosip2/eXosip.h. You need a working eXosip2 installation. See http://www.antisip.com/download/])
 fi
-libexosip_LIBS="-leXosip "
-SFLPHONE_LIBS="$SFLPHONE_LIBS $libexosip_LIBS"
+libexosip2_LIBS="-leXosip2 "
+SFLPHONE_LIBS="$SFLPHONE_LIBS $libexosip2_LIBS"
 
 AC_SUBST(LIBQT)
 
diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index b593b9bf13bd009a6656d9ea32920a156bb34425..5c43810e56db0742905eedb6926df8289f893fa9 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -189,6 +189,7 @@ AudioRtpRTX::initAudioRtpSession (void)
 			setCancel(cancelImmediate);
 		}
 	}
+	_debug("-----------------------\n");
 }
 
 void
diff --git a/src/gui/qt/qtGUImainwindow.cpp b/src/gui/qt/qtGUImainwindow.cpp
index 1b380ef9f764b7f40958d02770a902317c2ac705..8eb23f2ae41ca0a67ef34fd24ba448bc224a33b5 100644
--- a/src/gui/qt/qtGUImainwindow.cpp
+++ b/src/gui/qt/qtGUImainwindow.cpp
@@ -707,6 +707,7 @@ QtGUIMainWindow::callIsOnHold(int id, int line, int busyLine)
 int
 QtGUIMainWindow::callIsIncoming (int id, int line, int busyLine)
 {
+	_TabIncomingCalls[line] = -1;
 	changeLineStatePixmap(line, BUSY);
 	putOnHoldBusyLine(busyLine);
 	if (qt_answerCall(id) != 1) {
@@ -1218,6 +1219,7 @@ QtGUIMainWindow::hangupLine (void)
 			Manager::instance().displayErrorText("Hangup call failed !\n");
 		}	
 	} else if ((i = isThereIncomingCall()) > 0){
+		_debug("&&&&&&&&&& i = %d\n", i);
 		// To refuse new incoming call 
 		_debug("Refuse call %d\n", id);
 		if (qt_refuseCall(i)) {
diff --git a/src/gui/qt/qtGUImainwindow.h b/src/gui/qt/qtGUImainwindow.h
index a47f746526600417919f632d7527a34661fb1190..e9e58964e65c63bfb01eef2e71289c40615b2bfa 100644
--- a/src/gui/qt/qtGUImainwindow.h
+++ b/src/gui/qt/qtGUImainwindow.h
@@ -286,7 +286,7 @@ private:
 	inline void setPrevLine(int line) { _prevLine = line; }
 	inline int getPrevLine(void) { return _prevLine; }
 
-	// Array of incoming calls
+	// Array of incoming calls, contains call-id
 	int _TabIncomingCalls[NUMBER_OF_LINES];
 
 	// The current phoneline
diff --git a/src/sipcall.cpp b/src/sipcall.cpp
index 334c86b8b94d050daf765ceed0cace610727566a..90eb0b6b0765aeef8e1f4990c582301052a23d07 100644
--- a/src/sipcall.cpp
+++ b/src/sipcall.cpp
@@ -24,6 +24,12 @@
  
 #include <iostream>
 
+// For AF_INET
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+//
+
 #include "global.h"
 #include "audio/audiocodec.h"
 #include "audio/codecDescriptor.h"
@@ -95,6 +101,18 @@ SipCall::getCid (void)
 	return _cid;
 }
 
+void
+SipCall::setTid (int tid)
+{
+	_tid = tid;
+}
+
+int
+SipCall::getTid (void)
+{
+	return _tid;
+}
+
 int
 SipCall::getRemoteSdpAudioPort (void)
 {
@@ -124,187 +142,634 @@ int
 SipCall::newIncomingCall (eXosip_event_t *event) {	
 	SipCall *ca = this;
 	
+	sdp_message_t *remote_sdp = NULL;
+	
   	_cid = event->cid;
   	_did = event->did;
+  	_tid = event->tid;
 
   	if (_did < 1 && _cid < 1) {
+		exit(0);
       	return -1; /* not enough information for this event?? */
     }
 	
   	osip_strncpy (_textinfo, event->textinfo, 255);
-  	osip_strncpy (_req_uri, event->req_uri, 255);
-  	osip_strncpy (_local_uri, event->local_uri, 255);
-  	osip_strncpy (_local_uri, event->remote_uri, 255);
-  	osip_strncpy (_subject, event->subject, 255);
-	
-	osip_strncpy (ca->_remote_sdp_audio_ip, event->remote_sdp_audio_ip, 49);
-	ca->_remote_sdp_audio_port = event->remote_sdp_audio_port;
-	
-	ca->payload = event->payload;
-	_debug("For incoming ca->_payload = %d\n", ca->payload);
-	osip_strncpy (ca->_payload_name, event->payload_name, 49);
-	setAudioCodec(_cdv->at(0)->alloc(ca->payload, ca->_payload_name));	
-
-	osip_strncpy (ca->_sdp_body, event->sdp_body, 1000);
-	osip_strncpy (ca->_sdp_body, event->sdp_body, 1000);
-	_debug("\n%s\n", ca->_sdp_body);
-	
-  	if (event->reason_phrase[0] != '\0') {
-      	osip_strncpy(this->_reason_phrase, event->reason_phrase, 49);
-      	this->_status_code = event->status_code;
+
+	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;
+
+      	osip_from_to_str (event->request->from, &tmp);
+      	if (tmp != NULL) {
+          	snprintf (_remote_uri, 255, "%s", tmp);
+          	osip_free (tmp);
+        }
+    }
+
+	/* negotiate payloads */
+  	if (event->request != NULL) {
+      	remote_sdp = eXosip_get_sdp_info (event->request);
+    }
+
+  	if (remote_sdp == NULL) {
+      	_debug("missing SDP in INVITE request\n");
+    }
+
+  	if (remote_sdp != NULL) {      /* TODO: else build an offer */
+      	sdp_connection_t *conn;
+      	sdp_media_t *remote_med;
+		char *tmp = NULL;
+
+      	if (remote_sdp == NULL) {
+        	_debug("No remote SDP body found for call\n");
+			// Send 400 BAD REQUEST
+          	eXosip_call_send_answer (_tid, 400, NULL);
+	  		sdp_message_free (remote_sdp);
+          	return 0;
+        }
+
+      	conn = eXosip_get_audio_connection (remote_sdp);
+      	if (conn != NULL && conn->c_addr != NULL) {
+          	snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+        }
+      	remote_med = eXosip_get_audio_media (remote_sdp);
+
+      	if (remote_med == NULL || remote_med->m_port == NULL) {
+          	/* no audio media proposed */
+			// Send 415 Unsupported media type
+          	eXosip_call_send_answer (_tid, 415, NULL);
+	  		sdp_message_free (remote_sdp);
+          	return 0;
+        }
+
+      	_remote_sdp_audio_port = atoi (remote_med->m_port);
+
+		if (_remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') {
+			int pos;
+			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) {
+			ca->payload = atoi (tmp);
+		} else {
+			// Send 415 Unsupported media type
+			eXosip_call_send_answer (_tid, 415, NULL);
+			sdp_message_free (remote_sdp);
+			return 0;
+		}
+
+		if (tmp != NULL && (ca->payload == 0 || ca->payload == 8)
+		   && _remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') {
+		}
+    }
+
+  	if (remote_sdp != NULL) {       /* TODO: else build an offer */ 
+      	osip_message_t *answer;
+      	int i;
+
+      	eXosip_lock ();
+      	i = eXosip_call_build_answer (_tid, 183, &answer);
+      	if (i == 0) {
+          	i = sdp_complete_message (remote_sdp, answer);
+          	if (i != 0) {
+              	osip_message_free (answer);
+				// Send 415 Unsupported media type
+              	eXosip_call_send_answer (_tid, 415, NULL);
+          	} else {
+              	/* start sending audio */
+              	if (ca->enable_audio > 0) {
+                  	ca->enable_audio = -1;
+                }
+              	if (ca->enable_audio != 1)        /* audio is started */ {
+                  	sdp_message_t *local_sdp;
+                  	local_sdp = eXosip_get_sdp_info (answer);
+                  	if (remote_sdp != NULL && local_sdp != NULL) {
+                      	sdp_connection_t *conn;
+                      	sdp_media_t *local_med;
+                      	sdp_media_t *remote_med;
+                      	char *tmp = NULL;
+                      	int audio_port = 0;
+
+                      	conn = eXosip_get_audio_connection (remote_sdp);
+                      	if (conn != NULL && conn->c_addr != NULL) {
+                          	snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+                        }
+                      	remote_med = eXosip_get_audio_media (remote_sdp);
+                      	if (remote_med != NULL && remote_med->m_port != NULL) {
+                          	_remote_sdp_audio_port = atoi (remote_med->m_port);
+                        }
+                      	local_med = eXosip_get_audio_media (local_sdp);
+                      	if (local_med != NULL && local_med->m_port != NULL) {
+                          	audio_port = atoi (local_med->m_port);
+                        }
+
+                      	if (_remote_sdp_audio_port > 0
+                          && _remote_sdp_audio_ip[0] != '\0'
+                          && local_med != NULL) {
+                          	tmp = (char *) osip_list_get (local_med->m_payloads, 0);
+                        }
+                      	if (tmp != NULL) {
+                          	ca->payload = atoi (tmp);
+    						_debug("For incoming _payload = %d\n", ca->payload);
+    						setAudioCodec(_cdv->at(0)->alloc(ca->payload, ""));
+                        }
+						if (tmp != NULL
+                          && audio_port > 0
+                          && _remote_sdp_audio_port > 0
+                          && _remote_sdp_audio_ip[0] != '\0') {
+
+                          	/* 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);
+                          	if (_local_sendrecv == _SENDRECV) {
+                              	if (_remote_sendrecv == _SENDONLY)
+                                	_local_sendrecv = _RECVONLY;
+                              	else if (_remote_sendrecv == _RECVONLY)
+                                	_local_sendrecv = _SENDONLY;
+                            }
+						}
+                    }
+		  			sdp_message_free (local_sdp);
+           		}
+
+               	i = eXosip_call_send_answer (_tid, 183, answer);
+            }
+
+            if (i != 0) {
+              	_debug("cannot send 183 progress?\n");
+            }
+      	}
+      	eXosip_unlock ();
+    }
+
   	this->_state = event->type;
+	sdp_message_free (remote_sdp);
   	return 0;
 }
 
 
 int 
 SipCall::ringingCall (eXosip_event_t *event) {     
-	SipCall *ca = this;
+	SipCall* ca = this;
 	
     this->_cid = event->cid;
     this->_did = event->did;
+    this->_tid = event->tid;
       
     if (this->_did < 1 && this->_cid < 1) {
 	  return -1; 
 	}
 
-  	osip_strncpy(this->_textinfo,   event->textinfo, 255);
-  	osip_strncpy(this->_req_uri,    event->req_uri, 255);
-  	osip_strncpy(this->_local_uri,  event->local_uri, 255);
-  	osip_strncpy(this->_remote_uri, event->remote_uri, 255);
-  	osip_strncpy(this->_subject,    event->subject, 255);
+  	osip_strncpy (_textinfo, event->textinfo, 255);
 
-	osip_strncpy(ca->_remote_sdp_audio_ip, event->remote_sdp_audio_ip, 49);
-	ca->_remote_sdp_audio_port = event->remote_sdp_audio_port;
-	ca->payload = event->payload;
-	osip_strncpy(ca->_payload_name, event->payload_name, 49);
-	
-  	if (event->reason_phrase[0]!='\0') {
-      	osip_strncpy(this->_reason_phrase, event->reason_phrase, 49);
-      	this->_status_code = event->status_code;
+  	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;
+
+      	osip_from_to_str (event->request->from, &tmp);
+      	if (tmp != NULL) {
+          	snprintf (_remote_uri, 255, "%s", tmp);
+          	osip_free (tmp);
+        }
+    }
+
+    sdp_message_t *remote_sdp;
+    sdp_message_t *local_sdp;
+
+    local_sdp = eXosip_get_sdp_info (event->request);
+    remote_sdp = eXosip_get_sdp_info (event->response);
+    if (remote_sdp == NULL) {
+    	_debug("No remote SDP body found for call\n");
+          /* TODO: remote_sdp = retreive from ack above */
+    }
+    if (local_sdp == NULL) {
+    	_debug("SDP body was probably in the ACK (TODO)\n");
     }
+    if (remote_sdp != NULL && local_sdp != NULL) {
+        sdp_connection_t *conn;
+        sdp_media_t *local_med;
+        sdp_media_t *remote_med;
+        char *tmp = NULL;
+        int audio_port = 0;
+
+        conn = eXosip_get_audio_connection (remote_sdp);
+        if (conn != NULL && conn->c_addr != NULL) {
+        	snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+        }
+        remote_med = eXosip_get_audio_media (remote_sdp);
+        if (remote_med != NULL && remote_med->m_port != NULL) {
+        	_remote_sdp_audio_port = atoi (remote_med->m_port);
+        }
+        local_med = eXosip_get_audio_media (local_sdp);
+        if (local_med != NULL && local_med->m_port != NULL) {
+            audio_port = atoi (local_med->m_port);
+        }
+        if (_remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0' 
+				&& remote_med != NULL) {
+            tmp = (char *) osip_list_get (remote_med->m_payloads, 0);
+        }
+        if (tmp != NULL) {
+            ca->payload = atoi (tmp);
+        }
+        if (tmp != NULL
+              && audio_port > 0
+              && _remote_sdp_audio_port > 0
+              && _remote_sdp_audio_ip[0] != '\0') {
+			/* 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);
+            if (_local_sendrecv == _SENDRECV) {
+               	if (_remote_sendrecv == _SENDONLY)
+                   	_local_sendrecv = _RECVONLY;
+               	else if (_remote_sendrecv == _RECVONLY)
+                   	_local_sendrecv = _SENDONLY;
+            }
+		}
+	}
+    sdp_message_free (local_sdp);
+    sdp_message_free (remote_sdp);
+
   	this->_state = event->type;;
   	return 0;
 }
 
+int
+SipCall::receivedAck (eXosip_event_t *event)
+{
+	SipCall *ca = this;
+	
+    _cid = event->cid;
+    _did = event->did;
+
+
+  	if (event->ack != NULL) {
+      	sdp_message_t *remote_sdp;
+      	remote_sdp = eXosip_get_sdp_info (event->ack);
+      	if (remote_sdp != NULL) {
+	  		_debug("SDP detected in ACK!\n");
+		} else {
+	  		_debug("no SDP detected in ACK!\n");
+		}
+    }
+
+  	if (ca->enable_audio != 1) {   /* audio is started */
+      	sdp_message_t *remote_sdp;
+      	sdp_message_t *local_sdp;
+
+      	remote_sdp = eXosip_get_remote_sdp (_did);
+      	local_sdp = eXosip_get_local_sdp (_did);
+      	if (remote_sdp == NULL) {
+          	_debug("No remote SDP body found for call\n");
+        }
+      	if (remote_sdp != NULL && local_sdp != NULL) {
+          	sdp_connection_t *conn;
+          	sdp_media_t *local_med;
+          	sdp_media_t *remote_med;
+          	char *tmp = NULL;
+          	int audio_port = 0;
+
+          	conn = eXosip_get_audio_connection (remote_sdp);
+          	if (conn != NULL && conn->c_addr != NULL) {
+              	snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+            }
+          	remote_med = eXosip_get_audio_media (remote_sdp);
+          	if (remote_med != NULL && remote_med->m_port != NULL) {
+              	_remote_sdp_audio_port = atoi (remote_med->m_port);
+            }
+          	local_med = eXosip_get_audio_media (local_sdp);
+          	if (local_med != NULL && local_med->m_port != NULL) {
+              	audio_port = atoi (local_med->m_port);
+            }
+
+          	if (_remote_sdp_audio_port > 0
+              && _remote_sdp_audio_ip[0] != '\0' && local_med != NULL) {
+              	tmp = (char *) osip_list_get (local_med->m_payloads, 0);
+            }
+          	if (tmp != NULL) {
+              ca->payload = atoi (tmp);
+            }
+          	if (tmp != NULL
+              && audio_port > 0
+              && _remote_sdp_audio_port > 0
+              && _remote_sdp_audio_ip[0] != '\0') {
+
+              	/* 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);
+              	if (_local_sendrecv == _SENDRECV) {
+                  	if (_remote_sendrecv == _SENDONLY)
+                    	_local_sendrecv = _RECVONLY;
+                  	else if (_remote_sendrecv == _RECVONLY)
+                    	_local_sendrecv = _SENDONLY;
+                }
+            }
+        }
+      sdp_message_free (local_sdp);
+      sdp_message_free (remote_sdp);
+    }
+
+  _state = event->type;
+  return 0;
+}
 
 int 
 SipCall::answeredCall(eXosip_event_t *event) {
-	SipCall *ca = this;
-	
     _cid = event->cid;
     _did = event->did;
       
     if (_did < 1 && _cid < 1)	{
-	  return -1; /* not enough information for this event?? */
+		exit(0);
+	  	return -1; /* not enough information for this event?? */
 	}
-
 	osip_strncpy(this->_textinfo,   event->textinfo, 255);
-	osip_strncpy(this->_req_uri,    event->req_uri, 255);
-    osip_strncpy(this->_local_uri,  event->local_uri, 255);
-    osip_strncpy(this->_remote_uri, event->remote_uri, 255);
-    osip_strncpy(this->_subject,    event->subject, 255);
-
-	osip_strncpy(ca->_remote_sdp_audio_ip, event->remote_sdp_audio_ip, 49);
-	ca->_remote_sdp_audio_port = event->remote_sdp_audio_port;
-	osip_strncpy(ca->_payload_name, event->payload_name, 49);
-	osip_strncpy (ca->_sdp_body, event->sdp_body, 1000);
-	_debug("\n%s\n", ca->_sdp_body);
-
-	// For outgoing calls, find the first payload of the remote user
-	int i, size;
-	char temp[64];
-	bzero(temp, 64);
-	size = _cdv->size();
-	// Codec array in common with the 2 parts
-	int m_audio[size];
-	for (int a = 0; a < size; a++)
-		m_audio[a] = -1;
-	
-	sdp_message_t *sdp;
-	i = sdp_message_init(&sdp);
-	if (i != 0) _debug("Cannot allocate a SDP packet\n");
-	i = sdp_message_parse(sdp, ca->_sdp_body);
-	if (i != 0) _debug("Cannot parse the SDP body\n");
-	int pos = 0;
-	if (sdp == NULL) _debug("SDP = NULL\n");
-/*********/	
-	while (!sdp_message_endof_media (sdp, pos)) {
-		int k = 0;
-	    char *tmp = sdp_message_m_media_get (sdp, pos);
-		
-	    if (0 == osip_strncasecmp (tmp, "audio", 5)) {
-		  	char *payload = NULL;
-			int c = 0;
-		  	do {
-		    	payload = sdp_message_m_payload_get (sdp, pos, k);
-				for (int j = 0; j < size; j++) {
-					snprintf(temp, 63, "%d", _cdv->at(j)->getPayload());
-					if (payload != NULL and strcmp(temp, payload) == 0) {
-					   	m_audio[c] = _cdv->at(j)->getPayload();
-						c++;
-						break;
-					}
-				}
-				k++;
-			} while (payload != NULL);
-		}
-		pos++;
-	}
-/***********/
-	if (m_audio[0] == -1) {
-		noSupportedCodec();
-	} else {
-		ca->payload = m_audio[0];
-		setAudioCodec(_cdv->at(0)->alloc(ca->payload, ""));
-	}
 
-	_debug("For outgoing call: ca->_payload = %d\n", ca->payload);
-	
-	sdp_message_free(sdp);
+  	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;
 
-	if (event->reason_phrase[0]!='\0') {
-		osip_strncpy(this->_reason_phrase, event->reason_phrase, 49);
-		this->_status_code = event->status_code;
+      	osip_from_to_str (event->request->from, &tmp);
+      	if (tmp != NULL) {
+          	snprintf (_remote_uri, 255, "%s", tmp);
+          	osip_free (tmp);
+       	}
     }
+	
+  	eXosip_lock ();
+  	{
+    osip_message_t *ack = NULL;
+    int i;
+
+    i = eXosip_call_build_ack (_did, &ack);
+    if (i != 0) {
+    	_debug("Cannot build ACK for call!\n");
+    } else {
+        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("Cannot complete ACK with sdp body?!\n");
+            }
+        }
+		sdp_message_free (local_sdp);
+		sdp_message_free (remote_sdp);
+
+        eXosip_call_send_ack (_did, ack);
+   	}
+   }
+  	eXosip_unlock ();
+
 	this->_state = event->type;
 	return 0;
 }
 
-int
-SipCall::onholdCall (eXosip_event_t *event) {
+void
+SipCall::answeredCall_without_hold (eXosip_event_t *event) 
+{
 	SipCall *ca = this;
 
-	osip_strncpy(ca->_textinfo, event->textinfo, 255);
-
-    osip_strncpy(ca->_remote_sdp_audio_ip, event->remote_sdp_audio_ip, 49);
-    ca->_remote_sdp_audio_port = event->remote_sdp_audio_port;
+	if (ca->enable_audio == 1 && event->response != NULL) {
+      	sdp_message_t *sdp = eXosip_get_sdp_info (event->response);
+      	if (sdp != NULL) {
+	  		/* audio is started and session has just been modified */
+	  		ca->enable_audio = -1;
+	  		sdp_message_free (sdp);
+		}
+    }
 
-    osip_strncpy(ca->_reason_phrase, event->reason_phrase, 49);
-    ca->_status_code = event->status_code;
-		
-	ca->_state = event->type;
-  	return 0;
+  	if (ca->enable_audio != 1) {   /* audio is started */ 
+      	sdp_message_t *remote_sdp;
+      	sdp_message_t *local_sdp;
+
+      	local_sdp = eXosip_get_sdp_info (event->request);
+      	remote_sdp = eXosip_get_sdp_info (event->response);
+      	if (remote_sdp == NULL) {
+        	_debug("No remote SDP body found for call\n");
+          	/* TODO: remote_sdp = retreive from ack above */
+        }
+      	if (local_sdp == NULL) {
+          	_debug("SDP body was probably in the ACK (TODO)\n");
+        }
+
+	    if (remote_sdp != NULL && local_sdp != NULL) {
+          	sdp_connection_t *conn;
+          	sdp_media_t *local_med;
+          	sdp_media_t *remote_med;
+          	char *tmp = NULL;
+          	int audio_port = 0;
+
+          	conn = eXosip_get_audio_connection (remote_sdp);
+          	if (conn != NULL && conn->c_addr != NULL) {
+              	snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+            }
+          	remote_med = eXosip_get_audio_media (remote_sdp);
+          	if (remote_med != NULL && remote_med->m_port != NULL) {
+              	_remote_sdp_audio_port = atoi (remote_med->m_port);
+            }
+          	local_med = eXosip_get_audio_media (local_sdp);
+          	if (local_med != NULL && local_med->m_port != NULL) {
+              	audio_port = atoi (local_med->m_port);
+            }
+
+          	if (_remote_sdp_audio_port > 0
+              && _remote_sdp_audio_ip[0] != '\0' && remote_med != NULL) {
+              	tmp = (char *) osip_list_get (remote_med->m_payloads, 0);
+            }
+          	if (tmp != NULL) {
+              	ca->payload = atoi (tmp);
+				_debug("For outgoing call: ca->_payload = %d\n", ca->payload);
+				setAudioCodec(_cdv->at(0)->alloc(ca->payload, ""));
+            }
+			if (tmp != NULL
+              && audio_port > 0
+              && _remote_sdp_audio_port > 0
+              && _remote_sdp_audio_ip[0] != '\0') {
+
+              	/* 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);
+              	if (_local_sendrecv == _SENDRECV) {
+             		if (_remote_sendrecv == _SENDONLY)
+                    	_local_sendrecv = _RECVONLY;
+                  	else if (_remote_sendrecv == _RECVONLY)
+                    	_local_sendrecv = _SENDONLY;
+                }
+        	}
+		}
+    	sdp_message_free (local_sdp);
+    	sdp_message_free (remote_sdp);
+  	}
 }
 
 int
-SipCall::offholdCall (eXosip_event_t *event) {
-	SipCall *ca = this;
+SipCall::sdp_complete_message(sdp_message_t * remote_sdp, 
+		osip_message_t * msg)
+{
+  sdp_media_t *remote_med;
+  char *tmp = NULL;
+  char buf[4096];
+  int pos;
 
-	osip_strncpy(ca->_textinfo, event->textinfo, 255);
+  char localip[128];
 
-    osip_strncpy(ca->_remote_sdp_audio_ip, event->remote_sdp_audio_ip, 49);
-    ca->_remote_sdp_audio_port = event->remote_sdp_audio_port;
+  	// Format port to a char*
+  	char port_tmp[64];
+	bzero(port_tmp, 64);
+	snprintf(port_tmp, 63, "%d", _local_audio_port);
+	
+  	if (remote_sdp == NULL) {
+      	_debug("No remote SDP body found for call\n");
+      	return -1;
+    }
+  	if (msg == NULL) {
+    	_debug("No message to complete\n");
+      	return -1;
+    }
+
+  	eXosip_guess_localip (AF_INET, localip, 128);
+  	snprintf (buf, 4096,
+            "v=0\r\n"
+            "o=user 0 0 IN IP4 %s\r\n"
+            "s=session\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n", localip, localip);
+
+  	pos = 0;
+  	while (!osip_list_eol (remote_sdp->m_medias, pos)) {
+      	char payloads[128];
+      	int pos2;
+
+      	memset (payloads, '\0', sizeof (payloads));
+      	remote_med = (sdp_media_t *) osip_list_get (remote_sdp->m_medias, pos);
+
+      	if (0 == osip_strcasecmp (remote_med->m_media, "audio")) {
+          	pos2 = 0;
+          	while (!osip_list_eol (remote_med->m_payloads, pos2)) {
+              	tmp = (char *) osip_list_get (remote_med->m_payloads, pos2);
+              	if (tmp != NULL && 
+						(0 == osip_strcasecmp (tmp, "0")
+                   		|| 0 == osip_strcasecmp (tmp, "8")
+						|| 0 == osip_strcasecmp (tmp, "3"))) {
+                  	strcat (payloads, tmp);
+                  	strcat (payloads, " ");
+                }
+              	pos2++;
+            }
+          	strcat (buf, "m=");
+          	strcat (buf, remote_med->m_media);
+          	if (pos2 == 0 || payloads[0] == '\0') {
+              	strcat (buf, " 0 RTP/AVP \r\n");
+              	return -1;        /* refuse anyway */
+          	} else {
+			 	strcat (buf, " ");
+              	strcat (buf, port_tmp);
+              	strcat (buf, " RTP/AVP ");
+              	strcat (buf, payloads);
+              	strcat (buf, "\r\n");
+
+              	if (NULL != strstr (payloads, " 0 ")
+                  || (payloads[0] == '0' && payloads[1] == ' '))
+                	strcat (buf, "a=rtpmap:0 PCMU/8000\r\n");
+              	if (NULL != strstr (payloads, " 8 ")
+                  || (payloads[0] == '8' && payloads[1] == ' '))
+                	strcat (buf, "a=rtpmap:8 PCMA/8000\r\n");
+				if (NULL != strstr (payloads, " 3 ")
+                  || (payloads[0] == '8' && payloads[1] == ' '))
+                	strcat (buf, "a=rtpmap:8 GSM/8000\r\n");
+            }
+      	} else {
+          	strcat (buf, "m=");
+          	strcat (buf, remote_med->m_media);
+          	strcat (buf, " 0 ");
+          	strcat (buf, remote_med->m_proto);
+          	strcat (buf, " \r\n");
+        }
+      	pos++;
+    }
 
-    osip_strncpy(ca->_reason_phrase, event->reason_phrase, 49);
-    ca->_status_code = event->status_code;
-  
-	ca->_state = event->type;
+  	osip_message_set_body (msg, buf, strlen (buf));
+  	osip_message_set_content_type (msg, "application/sdp");
   	return 0;
 }
 
+int
+SipCall::sdp_analyse_attribute (sdp_message_t * sdp, sdp_media_t * med)
+{
+  	int pos;
+  	int pos_media;
+
+  	/* test media attributes */
+  	pos = 0;
+  	while (!osip_list_eol (med->a_attributes, pos)) {
+      	sdp_attribute_t *at;
+
+      	at = (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
+      	if (at->a_att_field != NULL && 
+				0 == strcmp (at->a_att_field, "sendonly")) {
+		  	return _SENDONLY;
+      	} else if (at->a_att_field != NULL &&
+                 0 == strcmp (at->a_att_field, "recvonly")) {
+          	return _RECVONLY;
+      	} else if (at->a_att_field != NULL &&
+                 0 == strcmp (at->a_att_field, "sendrecv")) {
+          	return _SENDRECV;
+        }
+      	pos++;
+    }
+
+  	/* test global attributes */
+  	pos_media = -1;
+  	pos = 0;
+  	while (!osip_list_eol (sdp->a_attributes, pos)) {
+      	sdp_attribute_t *at;
+
+      	at = (sdp_attribute_t *) osip_list_get (sdp->a_attributes, pos);
+      	if (at->a_att_field != NULL && 
+				0 == strcmp (at->a_att_field, "sendonly")) {
+          	return _SENDONLY;
+      	} else if (at->a_att_field != NULL &&
+                 0 == strcmp (at->a_att_field, "recvonly")) {
+          	return _RECVONLY;
+      	} else if (at->a_att_field != NULL &&
+                 0 == strcmp (at->a_att_field, "sendrecv")) {
+          	return _SENDRECV;
+        }
+      	pos++;
+    }
+
+  	return _SENDRECV;
+}
+
 void
 SipCall::alloc(void) {
 	this->_reason_phrase = new char[50];
diff --git a/src/sipcall.h b/src/sipcall.h
index 2b37a5d77b895ca5ad59d43b0c4663b16a15b1e6..6a8a38ba077b11747e1741440ff43154b6b9eb19 100644
--- a/src/sipcall.h
+++ b/src/sipcall.h
@@ -22,13 +22,16 @@
 #ifndef __SIP_CALL_H__
 #define __SIP_CALL_H__
 
-#include <eXosip/eXosip.h>
+#include <eXosip2/eXosip.h>
 #include <vector>
 
 class CodecDescriptor;
 class AudioCodec;
 
 #define NOT_USED      0
+#define _SENDRECV 0
+#define _SENDONLY 1
+#define _RECVONLY 2
 using namespace std;
 
 typedef vector<CodecDescriptor*, allocator<CodecDescriptor*> > CodecDescriptorVector;
@@ -43,9 +46,9 @@ public:
 	
 	int  	newIncomingCall 	(eXosip_event_t *);
 	int  	answeredCall 		(eXosip_event_t *);
+	void  	answeredCall_without_hold (eXosip_event_t *);
 	int  	ringingCall			(eXosip_event_t *);
-	int  	onholdCall			(eXosip_event_t *);
-	int  	offholdCall			(eXosip_event_t *);
+	int  	receivedAck			(eXosip_event_t *);
 
 	void	setLocalAudioPort 	(int);
 	int 	getLocalAudioPort 	(void);	
@@ -55,11 +58,15 @@ public:
 	int 	getDid				(void);
 	void 	setCid				(int cid);
 	int 	getCid				(void);
+	void 	setTid				(int tid);
+	int 	getTid				(void);
 	int 	getRemoteSdpAudioPort (void);
 	char* 	getRemoteSdpAudioIp (void);
 	AudioCodec* getAudioCodec	(void);
 	void	setAudioCodec		(AudioCodec* ac);
 
+	inline char* getRemoteUri (void) { return _remote_uri; }
+
 	inline void setStandBy (bool standby) { _standby = standby; }
 	inline bool getStandBy (void) { return _standby; }
 
@@ -67,6 +74,9 @@ private:
 	void	alloc			(void);
 	void	dealloc			(void);
 	void 	noSupportedCodec(void);	
+
+	int sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg);
+	int sdp_analyse_attribute (sdp_message_t * sdp, sdp_media_t * med);
 	
 	CodecDescriptorVector* _cdv;
 	AudioCodec* _audiocodec;
@@ -74,6 +84,7 @@ private:
 	short 	_id;
 	int 	_cid;	// call id
   	int 	_did;	// dialog id
+  	int 	_tid;	// transaction id
 	bool	_standby; // wait for a cid and did when outgoing call is made
 
   	int  	_status_code;
@@ -88,9 +99,12 @@ private:
 	char*	_remote_sdp_audio_ip;
   	char*	_payload_name;
 	char*	_sdp_body;
+	int		_payload;
   	int  	_state;
 	int		_local_audio_port;
   	int  	_remote_sdp_audio_port;
+	int 	_local_sendrecv;           /* _SENDRECV, _SENDONLY, _RECVONLY */
+  	int 	_remote_sendrecv;          /* _SENDRECV, _SENDONLY, _RECVONLY */
 };
 
 #endif // __SIP_CALL_H__
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index 300affeae41570f29b52e41a471fab828f1283ff..1594eaf1617a0ab7dcf25ef85b4236c7aa2d84dc 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -18,7 +18,7 @@
  */
 #include <sys/time.h>
 
-#include <eXosip/eXosip.h>  
+#include <eXosip2/eXosip.h>  
 #include <osip2/osip.h>
 #include <osipparser2/osip_const.h>
 #include <osipparser2/osip_headers.h>
@@ -87,16 +87,26 @@ int
 SipVoIPLink::init (void)
 {
 	string tmp;
+	int i;
 
 	tmp = string(PROGNAME) + "/" + string(VERSION);
 	
+	i = eXosip_init ();
+  	if (i != 0) {
+		_debug("Could not initialize eXosip\n");
+      	exit (0);
+    }
+	
 	srand (time(NULL));
-	if (eXosip_init (NULL, NULL, DEFAULT_SIP_PORT) != 0) {
-		if (eXosip_init (NULL, NULL, RANDOM_SIP_PORT) != 0) {
-			_debug("Cannot init eXosip\n");
+	i = eXosip_listen_addr(IPPROTO_UDP, NULL, DEFAULT_SIP_PORT, AF_INET, 0);
+	if (i != 0) {
+		i = eXosip_listen_addr(IPPROTO_UDP, NULL, RANDOM_SIP_PORT, AF_INET, 0);
+		if (i != 0) {
+			_debug("Could not initialize transport layer\n");
 			return -1;
 		}
 	}
+
 	// If use STUN server, firewall address setup
 	if (Manager::instance().useStun()) {
 		eXosip_set_user_agent(tmp.data());
@@ -104,11 +114,13 @@ SipVoIPLink::init (void)
 			return 0;
 		}
 
-		eXosip_set_firewallip((Manager::instance().getFirewallAddress()).data());
+		eXosip_masquerade_contact((Manager::instance().getFirewallAddress()).data(),
+				Manager::instance().getFirewallPort());
+		
 	} 
 	
 	eXosip_set_user_agent(tmp.data());
-	initRtpmapCodec();
+//	initRtpmapCodec();
 	_evThread->start();
 	return 1;
 }
@@ -126,33 +138,7 @@ SipVoIPLink::isInRtpmap (int index, int payload, CodecDescriptorVector* cdv) {
 void
 SipVoIPLink::initRtpmapCodec (void)
 {
-	int payload;
-	unsigned int nb;
-	char rtpmap[128];
-	char tmp[64];
 
-	bzero(rtpmap, 128);
-	bzero(tmp, 64);
-	
- 	/* reset all payload to fit application capabilities */
-  	eXosip_sdp_negotiation_remove_audio_payloads();
-	
-	// Set rtpmap according to the supported codec order
-	nb = Manager::instance().getNumberOfCodecs();
-	for (unsigned int i = 0; i < nb; i++) {
-		payload = Manager::instance().getCodecDescVector()->at(i)->getPayload();
-
-		// Add payload to rtpmap if it is not already added
-		if (!isInRtpmap(i, payload, Manager::instance().getCodecDescVector())) {
-			snprintf(rtpmap, 127, "%d %s/%d", payload, 
-				Manager::instance().getCodecDescVector()->at(i)->rtpmapPayload(payload).data(), SAMPLING_RATE);
-			snprintf(tmp, 63, "%d", payload);
-			
-			eXosip_sdp_negotiation_add_codec( osip_strdup(tmp), NULL,
-					   osip_strdup("RTP/AVP"), NULL, NULL, NULL, NULL,NULL,
-					   osip_strdup(rtpmap));
-		}
-	}
 }
 
 void
@@ -164,7 +150,9 @@ SipVoIPLink::quit(void)
 int
 SipVoIPLink::setRegister (void) 
 {
+	int i;
 	int reg_id = -1;
+	osip_message_t *reg = NULL;
 
 	string proxy = "sip:" + get_config_fields_str(SIGNALISATION, PROXY);
 
@@ -189,21 +177,20 @@ SipVoIPLink::setRegister (void)
 		return -1;
 	}
 	
-	_debug("register From: %s\n", from.data());
+	_debug("REGISTER From: %s\n", from.data());
 	if (!get_config_fields_str(SIGNALISATION, PROXY).empty()) {
-		reg_id = eXosip_register_init((char*)from.data(), 
-				(char*)proxy.data(),NULL); 
+		reg_id = eXosip_register_build_initial_register ((char*)from.data(), 
+				(char*)proxy.data(), NULL, EXPIRES_VALUE, &reg);
 	} else {
-		reg_id = eXosip_register_init((char*)from.data(),
-				(char*)hostname.data(), NULL);
+		reg_id = eXosip_register_build_initial_register ((char*)from.data(), 
+				(char*)hostname.data(), NULL, EXPIRES_VALUE, &reg);
 	}
 	if (reg_id < 0) {
 		eXosip_unlock();
 		return -1;
 	}	
-	
-	int i = eXosip_register(reg_id, EXPIRES_VALUE);
-	
+
+  	i = eXosip_register_send_register (reg_id, reg);
 	if (i == -2) {
 		_debug("cannot build registration, check the setup\n"); 
 		eXosip_unlock();
@@ -216,7 +203,7 @@ SipVoIPLink::setRegister (void)
 	}
 	
 	eXosip_unlock();
-	return 0;
+	return i;
 }
 int
 SipVoIPLink::outgoingInvite (short id, const string& to_url) 
@@ -271,6 +258,7 @@ int
 SipVoIPLink::answer (short id) 
 {
 	int i;
+	int port;
 	char tmpbuf[64];
 	bzero (tmpbuf, 64);
     // Get  port   
@@ -278,10 +266,34 @@ SipVoIPLink::answer (short id)
 	
 	_debug("Answer call [id = %d, cid = %d, did = %d]\n", 
 			id, getSipCall(id)->getCid(), getSipCall(id)->getDid());
-	_debug("Local audio port: %d\n", getSipCall(id)->getLocalAudioPort());
+	port = getSipCall(id)->getLocalAudioPort();
+	_debug("Local audio port: %d\n", port);
 	
+  
+	osip_message_t *answer = NULL;
+	SipCall* ca = getSipCall(id);
+
+	// Send 180 RINGING
+	eXosip_lock ();
+  	eXosip_call_send_answer (ca->getTid(), RINGING, NULL);
+  	eXosip_unlock ();
+
+	// Send 200 OK
 	eXosip_lock();
-    i = eXosip_answer_call(getSipCall(id)->getDid(), 200, tmpbuf);
+	i = eXosip_call_build_answer (ca->getTid(), OK, &answer);
+	if (i != 0) {
+		// Send 400 BAD_REQUEST
+     	eXosip_call_send_answer (ca->getTid(), BAD_REQ, NULL);
+  	} else {
+     	i = sdp_complete_200ok (ca->getDid(), answer, port);
+     	if (i != 0) {
+        	osip_message_free (answer);
+			// Send 415 UNSUPPORTED_MEDIA_TYPE
+        	eXosip_call_send_answer (ca->getTid(), UNSUP_MEDIA_TYPE, NULL);
+     	} else {
+        	eXosip_call_send_answer (ca->getTid(), OK, answer);
+		}
+  	}
 	eXosip_unlock();
 
 	// Incoming call is answered, start the sound channel.
@@ -301,7 +313,7 @@ SipVoIPLink::hangup (short id)
 				id, getSipCall(id)->getCid(), getSipCall(id)->getDid());	
 		// Release SIP stack.
 		eXosip_lock();
-		i = eXosip_terminate_call (getSipCall(id)->getCid(), 
+		i = eXosip_call_terminate (getSipCall(id)->getCid(), 
 									getSipCall(id)->getDid());
 		eXosip_unlock();
 
@@ -321,7 +333,7 @@ SipVoIPLink::cancel (short id)
 		_debug("Cancel call [id = %d, cid = %d]\n", id, getCid());
 		// Release SIP stack.
 		eXosip_lock();
-		i = eXosip_terminate_call (getCid(), -1);
+		i = eXosip_call_terminate (getCid(), -1);
 		eXosip_unlock();
 	}
 	deleteSipCall(id);
@@ -331,12 +343,64 @@ SipVoIPLink::cancel (short id)
 int
 SipVoIPLink::onhold (short id) 
 {
-	int i;
+	osip_message_t *invite;
+  	int i;
+	int did;
+
+  	sdp_message_t *local_sdp = NULL;
+
+	did = getSipCall(id)->getDid();
 	
-	eXosip_lock();
-	i = eXosip_on_hold_call(getSipCall(id)->getDid());
-	eXosip_unlock();
+  	eXosip_lock ();
+  	local_sdp = eXosip_get_local_sdp (did);
+  	eXosip_unlock ();
+	
+  	if (local_sdp == NULL) {
+    	return -1;
+	}
+
+/*
+  	char port[10];
+  	snprintf (port, 10, "%d", getSipCall(id)->getLocalAudioPort());
+	*/
 
+  	eXosip_lock ();
+	// Build INVITE_METHOD for put call on-hold
+  	i = eXosip_call_build_request (did, INVITE_METHOD, &invite);
+  	eXosip_unlock ();
+
+  	if (i != 0) {
+      	sdp_message_free(local_sdp);
+      	return -1;
+    }
+
+  	/* add sdp body */
+  {
+    char *tmp = NULL;
+    
+    i = sdp_hold_call (local_sdp);
+    if (i != 0) {
+		sdp_message_free (local_sdp);
+		osip_message_free (invite);
+		return -1;
+    }
+    
+    i = sdp_message_to_str (local_sdp, &tmp);
+    sdp_message_free (local_sdp);
+    if (i != 0) {
+		osip_message_free (invite);
+		return -1;
+    }
+    osip_message_set_body (invite, tmp, strlen (tmp));
+    osip_free (tmp);
+    osip_message_set_content_type (invite, "application/sdp");
+  }
+  
+  	eXosip_lock ();
+	// Send request
+  	i = eXosip_call_send_request (did, invite);
+  	eXosip_unlock ();
+  
 	// Disable audio
 	_audiortp->closeRtpSession(getSipCall(id));
 	return i;
@@ -345,12 +409,62 @@ SipVoIPLink::onhold (short id)
 int
 SipVoIPLink::offhold (short id) 
 {
-	int i;
-	
-	eXosip_lock();
-	i = eXosip_off_hold_call(getSipCall(id)->getDid(), NULL, 0);
-	eXosip_unlock();
+	osip_message_t *invite;
+  	int i;
+  	int did;
+
+  	sdp_message_t *local_sdp = NULL;
+
+  	did = getSipCall(id)->getDid();
+  	eXosip_lock ();
+  	local_sdp = eXosip_get_local_sdp (did);
+  	eXosip_unlock ();
+  	if (local_sdp == NULL) {
+    	return -1;
+	}
+
+	/*
+  	char port[10];
+  	snprintf (port, 10, "%d", getSipCall(id)->getLocalAudioPort());
+	*/
 
+  	eXosip_lock ();
+	// Build INVITE_METHOD for put call off-hold
+  	i = eXosip_call_build_request (did, INVITE_METHOD, &invite);
+  	eXosip_unlock ();
+
+  	if (i != 0) {
+      	sdp_message_free(local_sdp);
+      	return -1;
+    }
+
+  /* add sdp body */
+  {
+    char *tmp = NULL;
+    
+    i = sdp_off_hold_call (local_sdp);
+    if (i != 0) {
+		sdp_message_free (local_sdp);
+		osip_message_free (invite);
+		return -1;
+    }
+    
+    i = sdp_message_to_str (local_sdp, &tmp);
+    sdp_message_free (local_sdp);
+    if (i != 0) {
+		osip_message_free (invite);
+		return -1;
+    }
+    osip_message_set_body (invite, tmp, strlen (tmp));
+    osip_free (tmp);
+    osip_message_set_content_type (invite, "application/sdp");
+  }
+
+  	eXosip_lock ();
+	// Send request
+  	i = eXosip_call_send_request (did, invite);
+  	eXosip_unlock ();
+  
 	// Enable audio
 	if (_audiortp->createNewSession (getSipCall(id)) < 0) {
 		_debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__);
@@ -362,6 +476,7 @@ SipVoIPLink::offhold (short id)
 int
 SipVoIPLink::transfer (short id, const string& to)
 {
+	osip_message_t *refer;
 	int i;
 	string tmp_to;
 	tmp_to = toHeader(to);
@@ -370,7 +485,13 @@ SipVoIPLink::transfer (short id, const string& to)
 	}
 
 	eXosip_lock();
-	i = eXosip_transfer_call(getSipCall(id)->getDid(), (char*)tmp_to.data());
+	// Build transfer request
+	i = eXosip_call_build_refer (getSipCall(id)->getDid(), (char*)tmp_to.data(),
+		   &refer);
+	if (i == 0) {
+		// Send transfer request
+		i = eXosip_call_send_request (getSipCall(id)->getDid(), refer);
+    }
 	eXosip_unlock();
 	return i;
 }
@@ -384,8 +505,12 @@ SipVoIPLink::refuse (short id)
     // Get local port   
     snprintf (tmpbuf, 63, "%d", getSipCall(id)->getLocalAudioPort());
 	
+	osip_message_t *answer = NULL;
 	eXosip_lock();
-	i = eXosip_answer_call(getSipCall(id)->getDid(), BUSY_HERE, tmpbuf);
+	i = eXosip_call_build_answer (getSipCall(id)->getTid(), BUSY_HERE, &answer);
+	if (i == 0) {
+	  i = eXosip_call_send_answer (getSipCall(id)->getTid(), BUSY_HERE, answer);
+	}
 	eXosip_unlock();
 	return i;
 }
@@ -396,16 +521,18 @@ SipVoIPLink::getEvent (void)
 	eXosip_event_t *event;
 	short id;
 	char *name;
-	static int countReg = 0;
 
-	eXosip_automatic_refresh();
 	event = eXosip_event_wait (0, 50);
+	eXosip_lock();
+	eXosip_automatic_action();
+	eXosip_unlock();
+
 	if (event == NULL) {
 		return -1;
 	}	
 	switch (event->type) {
 		// IP-Phone user receives a new call
-		case EXOSIP_CALL_NEW: //
+		case EXOSIP_CALL_INVITE: //
 			// Set local random port for incoming call
 			if (!Manager::instance().useStun()) {
 				setLocalPort(RANDOM_LOCAL_PORT);
@@ -418,6 +545,7 @@ SipVoIPLink::getEvent (void)
 				}	
 			}
 			
+			// Generate id
 			id = Manager::instance().generateNewCallId();
 			Manager::instance().pushBackNewCall(id, Incoming);
 			_debug("Incoming Call with identifiant %d [cid = %d, did = %d]\n",
@@ -427,7 +555,17 @@ SipVoIPLink::getEvent (void)
 			// Display the callerId-name
 			osip_from_t *from;
   			osip_from_init(&from);
-  			osip_from_parse(from, event->remote_uri);
+
+			if (event->request != NULL) {
+      			char *tmp = NULL;
+
+      			osip_from_to_str (event->request->from, &tmp);
+      			if (tmp != NULL) {
+          			snprintf (getSipCall(id)->getRemoteUri(), 256, "%s", tmp);
+          			osip_free (tmp);
+        		}
+    		}
+  			osip_from_parse(from, getSipCall(id)->getRemoteUri());
 			name = osip_from_get_displayname(from);
 			Manager::instance().displayTextMessage(id, name);
 			if (Manager::instance().getCall(id) != NULL) {
@@ -438,15 +576,16 @@ SipVoIPLink::getEvent (void)
 			_debug("From: %s\n", name);
 			osip_from_free(from);
 			
+			// Associate an audio port with a call
+			getSipCall(id)->setLocalAudioPort(_localPort);
+
+			
 			getSipCall(id)->newIncomingCall(event);
 			if (Manager::instance().incomingCall(id) < 0) {
 				Manager::instance().displayErrorText("Incoming call failed");
 				return -1;
 			}
 
-			// Associate an audio port with a call
-			getSipCall(id)->setLocalAudioPort(_localPort);
-			
 			break;
 
 		// The peer-user answers
@@ -463,6 +602,7 @@ SipVoIPLink::getEvent (void)
 					   and !Manager::instance().getCall(id)->isOffHold()) {
 				getSipCall(id)->setStandBy(false);
 				if (getSipCall(id)->answeredCall(event) != -1) {
+					getSipCall(id)->answeredCall_without_hold(event);
 					Manager::instance().peerAnsweredCall(id);
 
 					// Outgoing call is answered, start the sound channel.
@@ -472,9 +612,15 @@ SipVoIPLink::getEvent (void)
 						exit(1);
 					}
 				}
+			} else {
+			// Answer to on/off hold to send ACK
+				if (id > 0) {
+					getSipCall(id)->answeredCall(event);
+					_debug("-----------------------\n");
+				}
 			}
 			break;
-
+			
 		case EXOSIP_CALL_RINGING: //peer call is ringing
 			id = findCallIdWhenRinging();
 			
@@ -492,6 +638,17 @@ SipVoIPLink::getEvent (void)
 		case EXOSIP_CALL_REDIRECTED:
 			break;
 
+		case EXOSIP_CALL_ACK:
+			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);
+			} else {
+				return -1;
+			}
+			break;
+			
 		// The peer-user closed the phone call(we received BYE).
 		case EXOSIP_CALL_CLOSED:
 			id = findCallId(event);
@@ -509,35 +666,14 @@ SipVoIPLink::getEvent (void)
 			}	
 			break;
 
-		case EXOSIP_CALL_HOLD:
-			id = findCallId(event);
-			if (id > 0) {
-				getSipCall(id)->onholdCall(event);
-			} else {
-			   return -1;
-			}	   
-			break;
-
-		case EXOSIP_CALL_OFFHOLD:
-			id = findCallId(event);
-			if (id > 0) {
-				getSipCall(id)->offholdCall(event);
-			} else {
-				return -1;
-			}
-			break;
-			
 		case EXOSIP_CALL_REQUESTFAILURE:
 			id = findCallId(event);
 
 			// Handle 4XX errors
-			switch (event->status_code) {
+			switch (event->response->status_code) {
 				case AUTH_REQUIRED:
-					if (setAuthentication() == -1) {
-						break;
-					}
 					eXosip_lock();
-					eXosip_retry_call (event->cid);
+					eXosip_automatic_action();
 					eXosip_unlock();
 					break;
 				case BAD_REQ:
@@ -551,7 +687,7 @@ SipVoIPLink::getEvent (void)
 				case ADDR_INCOMPLETE:
 				case BUSY_HERE:
 					// Display error on the screen phone
-					Manager::instance().displayError(event->reason_phrase);
+					Manager::instance().displayError(event->response->reason_phrase);
 					Manager::instance().congestion(true);
 					break;
 				case REQ_TERMINATED:
@@ -563,7 +699,7 @@ SipVoIPLink::getEvent (void)
 
 		case EXOSIP_CALL_SERVERFAILURE:
 			// Handle 5XX errors
-			switch (event->status_code) {
+			switch (event->response->status_code) {
 				case SERVICE_UNAVAILABLE:
 					Manager::instance().ringback(false);
 					Manager::instance().congestion(true);					
@@ -575,7 +711,7 @@ SipVoIPLink::getEvent (void)
 
 		case EXOSIP_CALL_GLOBALFAILURE:
 			// Handle 6XX errors
-			switch (event->status_code) {
+			switch (event->response->status_code) {
 				case BUSY_EVERYWHERE:
 				case DECLINE:
 					Manager::instance().ringback(false);
@@ -587,64 +723,36 @@ SipVoIPLink::getEvent (void)
 			break;
 
 		case EXOSIP_REGISTRATION_SUCCESS:
-			_debug("-- Registration succeeded --\n");
 			Manager::instance().displayStatus(LOGGED_IN_STATUS);
 			break;
 
 		case EXOSIP_REGISTRATION_FAILURE:
-			_debug("-- Registration failed --\n");
-			if (countReg <= 3) { 
-				setRegister();
-				countReg++;
-			} 
-			
 			break;
 
-		case EXOSIP_OPTIONS_NEW:
-			/* answer the OPTIONS method */
-			/* 1: search for an existing call */
+		case EXOSIP_MESSAGE_NEW:
 			unsigned int k;
 				
-			for (k = 0; k < _sipcallVector->size(); k++) {
-				if (_sipcallVector->at(k)->getCid() == event->cid) { 
-					break;
+			if (event->request != NULL && MSG_IS_OPTIONS(event->request)) {
+				for (k = 0; k < _sipcallVector->size(); k++) {
+					if (_sipcallVector->at(k)->getCid() == event->cid) { 
+						break;
+					}
 				}
+			
+				// TODO: Que faire si rien trouve??
+				eXosip_lock();
+				if (_sipcallVector->at(k)->getCid() == event->cid) {
+					/* already answered! */
+				}
+				else if (k == _sipcallVector->size()) {
+					/* answer 200 ok */
+					eXosip_options_send_answer (event->tid, OK, NULL);
+				} else {
+					/* answer 486 ok */
+					eXosip_options_send_answer (event->tid, BUSY_HERE, NULL);
+				}
+				eXosip_unlock();
 			}
-		
-			// TODO: Que faire si rien trouve??
-			eXosip_lock();
-			if (_sipcallVector->at(k)->getCid() == event->cid) {
-				/* already answered! */
-			}
-			else if (k == _sipcallVector->size()) {
-				/* answer 200 ok */
-				eXosip_answer_options (event->cid, event->did, 200);
-			} else {
-				/* answer 486 ok */
-				eXosip_answer_options (event->cid, event->did, 486);
-			}
-			eXosip_unlock();
-			break;
-
-		case EXOSIP_OPTIONS_ANSWERED:
-			break;
-
-		case EXOSIP_OPTIONS_PROCEEDING:
-			break;
-
-		case EXOSIP_OPTIONS_REDIRECTED:
-			break;
-
-		case EXOSIP_OPTIONS_REQUESTFAILURE:
-			break;
-
-		case EXOSIP_OPTIONS_SERVERFAILURE:
-			break;
-
-		case EXOSIP_OPTIONS_GLOBALFAILURE:
-			break;
-
-		case EXOSIP_SUBSCRIPTION_NOTIFY:
 			break;
 
 		default:
@@ -671,17 +779,23 @@ SipVoIPLink::setLocalPort (int port)
 void
 SipVoIPLink::carryingDTMFdigits (short id, char code) {
 	  int duration = get_config_fields_int(SIGNALISATION, PULSE_LENGTH);
-      
-	  static const int body_len = 128;
+      osip_message_t *info;
+	  const int body_len = 1000;
+	  int i;
 
       char *dtmf_body = new char[body_len];
-	  snprintf(dtmf_body, body_len - 1,
-			  "Signal=%c\r\nDuration=%d\r\n",
-			  code, duration);
 
       eXosip_lock();
-      eXosip_info_call(getSipCall(id)->getDid(), "application/dtmf-relay", 
-			  dtmf_body);
+	  // Build info request
+	  i = eXosip_call_build_info (getSipCall(id)->getDid(), &info);
+	  if (i == 0) {
+	  		snprintf(dtmf_body, body_len - 1, "Signal=%c\r\nDuration=%d\r\n",
+			  code, duration);
+     		osip_message_set_content_type (info, "application/dtmf-relay");
+     		osip_message_set_body (info, dtmf_body, strlen (dtmf_body));
+			// Send info request
+     		i = eXosip_call_send_request (getSipCall(id)->getDid(), info);
+  	  }
       eXosip_unlock();
 	
 	  delete[] dtmf_body;
@@ -741,6 +855,178 @@ SipVoIPLink::getAudioCodec (short callid)
 ///////////////////////////////////////////////////////////////////////////////
 // Private functions
 ///////////////////////////////////////////////////////////////////////////////
+int
+SipVoIPLink::sdp_hold_call (sdp_message_t * sdp)
+{
+  	int pos;
+  	int pos_media = -1;
+  	char *rcvsnd;
+  	int recv_send = -1;
+
+  	pos = 0;
+  	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+  	while (rcvsnd != NULL) {
+      	if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "sendonly")) {
+          	recv_send = 0;
+      	} else if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "recvonly")
+                                    || 0 == strcmp (rcvsnd, "sendrecv"))) {
+          	recv_send = 0;
+          	sprintf (rcvsnd, "sendonly");
+        }
+      	pos++;
+      	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+    }
+
+  	pos_media = 0;
+  	while (!sdp_message_endof_media (sdp, pos_media)) {
+      	pos = 0;
+      	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+      	while (rcvsnd != NULL) {
+          	if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "sendonly")) {
+              	recv_send = 0;
+          	} else if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "recvonly")
+                                        || 0 == strcmp (rcvsnd, "sendrecv"))) {
+            	recv_send = 0;
+            	sprintf (rcvsnd, "sendonly");
+            }
+          	pos++;
+          	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+        }
+      	pos_media++;
+    }
+
+  	if (recv_send == -1) {
+      	/* we need to add a global attribute with a field set to "sendonly" */
+      	sdp_message_a_attribute_add (sdp, -1, osip_strdup ("sendonly"), NULL);
+    }
+  	return 0;
+}
+
+int
+SipVoIPLink::sdp_off_hold_call (sdp_message_t * sdp)
+{
+  	int pos;
+  	int pos_media = -1;
+  	char *rcvsnd;
+
+  	pos = 0;
+  	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+  	while (rcvsnd != NULL) {
+      	if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "sendonly")
+                             || 0 == strcmp (rcvsnd, "recvonly"))) {
+          	sprintf (rcvsnd, "sendrecv");
+        }
+      	pos++;
+      	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+    }
+
+  	pos_media = 0;
+  	while (!sdp_message_endof_media (sdp, pos_media)) {
+      	pos = 0;
+      	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+      	while (rcvsnd != NULL) {
+          	if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "sendonly")
+                                 || 0 == strcmp (rcvsnd, "recvonly"))) {
+              	sprintf (rcvsnd, "sendrecv");
+            }
+          	pos++;
+          	rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
+        }
+      	pos_media++;
+    }
+
+  	return 0;
+}
+
+int
+SipVoIPLink::sdp_complete_200ok (int did, osip_message_t * answer, int port)
+{
+	sdp_message_t *remote_sdp;
+  	sdp_media_t *remote_med;
+  	char *tmp = NULL;
+  	char buf[4096];
+  	char port_tmp[64];
+	int pos;
+
+	char localip[128];
+
+	// Format port to a char*
+	bzero(port_tmp, 64);
+	snprintf(port_tmp, 63, "%d", port);
+
+	remote_sdp = eXosip_get_remote_sdp (did);
+	if (remote_sdp == NULL) {
+		  return -1;                /* no existing body? */
+	}
+
+	eXosip_guess_localip (AF_INET, localip, 128);
+	snprintf (buf, 4096,
+				"v=0\r\n"
+				"o=user 0 0 IN IP4 %s\r\n"
+				"s=session\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n", localip,localip);
+
+	pos = 0;
+	while (!osip_list_eol (remote_sdp->m_medias, pos)) {
+		char payloads[128];
+		int pos2;
+
+		memset (payloads, '\0', sizeof (payloads));
+		remote_med = (sdp_media_t *) osip_list_get (remote_sdp->m_medias, pos);
+
+		if (0 == osip_strcasecmp (remote_med->m_media, "audio")) {
+			pos2 = 0;
+			while (!osip_list_eol (remote_med->m_payloads, pos2)) {
+				tmp = (char *) osip_list_get (remote_med->m_payloads, pos2);
+				if (tmp != NULL && (0 == osip_strcasecmp (tmp, "0")
+					   || 0 == osip_strcasecmp (tmp, "8")
+					   || 0 == osip_strcasecmp (tmp, "3"))) {
+			    	strcat (payloads, tmp);
+					strcat (payloads, " ");
+				}
+				pos2++;
+			}
+			strcat (buf, "m=");
+			strcat (buf, remote_med->m_media);
+			if (pos2 == 0 || payloads[0] == '\0') {
+				strcat (buf, " 0 RTP/AVP \r\n");
+			    sdp_message_free (remote_sdp);
+				return -1;        /* refuse anyway */
+			} else {
+				strcat (buf, " ");
+				strcat (buf, port_tmp);
+				strcat (buf, " RTP/AVP ");
+				strcat (buf, payloads);
+				strcat (buf, "\r\n");
+
+				if (NULL != strstr (payloads, " 0 ")
+				  || (payloads[0] == '0' && payloads[1] == ' ')) {
+					strcat (buf, "a=rtpmap:0 PCMU/8000\r\n");
+				}
+				if (NULL != strstr (payloads, " 8 ")
+				  || (payloads[0] == '8' && payloads[1] == ' ')) {
+					strcat (buf, "a=rtpmap:8 PCMA/8000\r\n");
+				}
+				if (NULL != strstr (payloads, " 3")
+				  || (payloads[0] == '3' && payloads[1] == ' ')) {
+					strcat (buf, "a=rtpmap:3 GSM/8000\r\n");
+				}
+			}
+		} else {
+			strcat (buf, "m=");
+			strcat (buf, remote_med->m_media);
+			strcat (buf, " 0 ");
+			strcat (buf, remote_med->m_proto);
+			strcat (buf, " \r\n");
+		}
+		pos++;
+	}
+
+	osip_message_set_body (answer, buf, strlen (buf));
+	osip_message_set_content_type (answer, "application/sdp");
+	sdp_message_free (remote_sdp);
+	return 0;
+}
+
 
 int
 SipVoIPLink::behindNat (void)
@@ -852,18 +1138,10 @@ SipVoIPLink::startCall (short id, const string& from, const string& to,
 		Manager::instance().error()->errorName(TO_ERROR);
     	return -1;
   	}
-  	
-	i = eXosip_build_initial_invite(&invite,(char*)to.data(),(char*)from.data(),
-		   						(char*)route.data(), (char*)subject.data());	
-  	if (i != 0) {
-		return -1;
-    }
-  	
-	eXosip_lock();
 	
 	char port[64];
 	if (!Manager::instance().useStun()) {
-		// Set random port for outgoing call
+		// Set random port for outgoing call if no firewall
 		setLocalPort(RANDOM_LOCAL_PORT);
 		_debug("Local audio port: %d\n",_localPort);
 	} else {
@@ -876,6 +1154,7 @@ SipVoIPLink::startCall (short id, const string& from, const string& to,
 		}
 	}
 	
+	// Set local audio port for sipcall(id)
 	if (getSipCall(id) != NULL) {
 		getSipCall(id)->setLocalAudioPort(_localPort);
 	} else {
@@ -884,12 +1163,73 @@ SipVoIPLink::startCall (short id, const string& from, const string& to,
 	
 	bzero (port, 64);
 	snprintf (port, 63, "%d", getLocalPort());
-		
-	i = eXosip_initiate_call(invite, NULL, NULL, port);
+  	
+	i = eXosip_call_build_initial_invite (&invite, (char*)to.data(),
+                                        (char*)from.data(),
+                                        (char*)route.data(),
+                                        (char*)subject.data());
+  	if (i != 0) {
+		return -1;
+    }
+  	
+
+	int payload;
+	unsigned int nb;
+	char rtpmap[128];
+	char rtpmap_attr[2048];
+	char media[64];
+	char media_audio[64];
+
+	bzero(rtpmap, 128);
+	bzero(rtpmap_attr, 2048);
+	bzero(media, 64);
+	bzero(media_audio, 64);
+	
+	// Set rtpmap according to the supported codec order
+	nb = Manager::instance().getNumberOfCodecs();
+	for (unsigned int i = 0; i < nb; i++) {
+		payload = Manager::instance().getCodecDescVector()->at(i)->getPayload();
+
+		// Add payload to rtpmap if it is not already added
+		if (!isInRtpmap(i, payload, Manager::instance().getCodecDescVector())) {
+			snprintf(media, 63, "%d ", payload);
+			strcat (media_audio, media);
+			
+			snprintf(rtpmap, 127, "a=rtpmap: %d %s/%d\r\n", payload, 
+				Manager::instance().getCodecDescVector()->at(i)->rtpmapPayload(payload).data(), SAMPLING_RATE);
+			strcat(rtpmap_attr, rtpmap); 
+		}
+	}
+
+  /* add sdp body */
+  {
+    char tmp[4096];
+    char localip[128];
+
+    eXosip_guess_localip (AF_INET, localip, 128);
+    snprintf (tmp, 4096,
+              "v=0\r\n"
+              "o=SFLphone 0 0 IN IP4 %s\r\n"
+              "s=call\r\n"
+              "c=IN IP4 %s\r\n"
+              "t=0 0\r\n"
+              "m=audio %s RTP/AVP %s\r\n"
+			  "%s",
+              localip, localip, port, media_audio, rtpmap_attr);
+	
+    osip_message_set_body (invite, tmp, strlen (tmp));
+    osip_message_set_content_type (invite, "application/sdp");
+  }
+  
+	eXosip_lock();
+	
+	i = eXosip_call_send_initial_invite (invite);
 
 	if (i <= 0) {
 		eXosip_unlock();
 		return -1;
+	} else {
+		eXosip_call_set_reference (i, NULL);
 	}
 
 	eXosip_unlock();
diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h
index ae34952765d451170a34e07bf43b51e8f2637c04..fbcbf7d9c3f3469e67918f9ecf37323fcfdf97c4 100644
--- a/src/sipvoiplink.h
+++ b/src/sipvoiplink.h
@@ -20,7 +20,8 @@
 #ifndef __SIP_VOIP_LINK_H__
 #define __SIP_VOIP_LINK_H__
 
-#include <eXosip/eXosip.h>
+#include <eXosip2/eXosip.h>
+#include <osipparser2/sdp_message.h>
 
 #include <string>
 #include <vector>
@@ -30,8 +31,12 @@
 using namespace std;
 
 #define EXPIRES_VALUE	180
+#define INVITE_METHOD	"INVITE"
 // 1XX responses
 #define DIALOG_ESTABLISHED 101
+#define RINGING			180
+// 2XX
+#define OK				200
 // 4XX Errors
 #define	BAD_REQ			400
 #define	UNAUTHORIZED	401
@@ -41,6 +46,7 @@ using namespace std;
 #define NOT_ACCEPTABLE	406
 #define AUTH_REQUIRED	407
 #define REQ_TIMEOUT		408
+#define UNSUP_MEDIA_TYPE	415
 #define TEMP_UNAVAILABLE 480
 #define	ADDR_INCOMPLETE	484
 #define	BUSY_HERE		486
@@ -122,6 +128,21 @@ private:
 	short findCallId (eXosip_event_t *e);
 	short findCallIdWhenRinging (void);
 	bool isInRtpmap (int index, int payload, CodecDescriptorVector* cdv);
+
+	/*
+	 * To build sdp with 200 OK when answered call
+	 */
+	int sdp_complete_200ok(int did, osip_message_t * answer, int port);
+	
+	/*
+	 * To build sdp when call is on-hold
+	 */
+	int sdp_hold_call (sdp_message_t * sdp);
+	
+	/*
+	 * To build sdp when call is off-hold
+	 */
+	int sdp_off_hold_call (sdp_message_t * sdp);
 	
 	EventThread* 	_evThread;
 	SipCallVector* 	_sipcallVector;