diff --git a/src/Makefile.am b/src/Makefile.am
index e0a77e282182d317e1214f753d2e1482d6d0b72f..7af7dbfec2d5350a0c1b9aa2d9cc6cfa4ec44835 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,7 @@ sflphoned_SOURCES = \
 		account.cpp \
 		sipcall.cpp \
 		sdp.cpp \
+		sdpmedia.cpp \
 		$(IAXSOURCES) 
 
 sflphoned_CXXFLAGS = \
@@ -69,7 +70,8 @@ noinst_HEADERS = \
         sipvoiplink.h \
 		call.h \
 		sipcall.h \
-		sdp.h
+		sdp.h \
+		sdpmedia.h
 		
 libsflphone_la_LIBADD = \
 	$(src)/libs/stund/libstun.la \
diff --git a/src/sdp.cpp b/src/sdp.cpp
index f89dd5b540cd059ce35b3e6d8bc451e32fa1075a..7b847bbbeab70e4bf26d0ab98f424d47e951032f 100644
--- a/src/sdp.cpp
+++ b/src/sdp.cpp
@@ -20,368 +20,336 @@
 
 #include "sdp.h"
 #include "global.h"
+#include "manager.h"
 
-#define _SENDRECV 0
-#define _SENDONLY 1
-#define _RECVONLY 2
 
-    Sdp::Sdp( pj_pool_t *pool ) :  _localSDP(NULL)
-    , _negociator(NULL)
-    , _codecMap()
-    , _audioCodec()
-    , _ipAddr("")
+static const pj_str_t STR_AUDIO = { (char*)"audio", 5};
+static const pj_str_t STR_VIDEO = { (char*)"video", 5};
+static const pj_str_t STR_IN = { (char*)"IN", 2 };
+static const pj_str_t STR_IP4 = { (char*)"IP4", 3};
+static const pj_str_t STR_IP6 = { (char*)"IP6", 3};
+static const pj_str_t STR_RTP_AVP = { (char*)"RTP/AVP", 7 };
+static const pj_str_t STR_SDP_NAME = { (char*)"sflphone", 7 };
+static const pj_str_t STR_SENDRECV = { (char*)"sendrecv", 8 };
+
+    Sdp::Sdp( pj_pool_t *pool ) 
+        : _local_media_cap(), _session_media(0),  _ip_addr( "" ), _local_offer( NULL ), _negociated_offer(NULL), _negociator(NULL), _pool(NULL) 
 {
     _pool = pool;
 }
 
-Sdp::~Sdp() {}
+Sdp::~Sdp() {
 
-    bool 
-Sdp::SIPCallInvite(pjsip_rx_data *rdata)
-{
-    pj_status_t status;
+    unsigned int k;
 
-    // We retrieve the remote sdp offer in the rdata struct to begin the negociation
-    pjmedia_sdp_session* remote_sdp = getRemoteSDPFromRequest(rdata);
-    if (remote_sdp == 0) {
-        _debug ("Failed to retrieve the remote sdp offer in the rdata struct to begin the negociation\n");
-        return false;
+    for( k=0; k<_session_media.size(); k++ ){
+        delete _session_media[k];
+        _session_media[k] = 0;
     }
+}
 
-    // Have to do some stuff here with the SDP
-    _localSDP = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_session);
-    _localSDP->conn =  PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_conn);
+void Sdp::set_media_descriptor_line( sdpMedia *media,
+                                  pjmedia_sdp_media** p_med ) {
+    pjmedia_sdp_media* med;
+    pjmedia_sdp_rtpmap rtpmap;
+    pjmedia_sdp_attr *attr;
+    AudioCodec *codec;
+    int count, i;
+    std::ostringstream tmp;
 
-    _localSDP->origin.version = 0;
-    sdpAddOrigin();
-    _localSDP->name = pj_str((char*)"sflphone");
-    sdpAddConnectionInfo();
-    _localSDP->time.start = _localSDP->time.stop = 0;
-    sdpAddMediaDescription();
+    med = PJ_POOL_ZALLOC_T( _pool, pjmedia_sdp_media );
 
-    // DEBUG
-    toString ();
+    // Get the right media format
+    pj_strdup(_pool, &med->desc.media,
+              ( media->get_media_type() == MIME_TYPE_AUDIO ) ? &STR_AUDIO : &STR_VIDEO );
+    med->desc.port_count = 1;
+    med->desc.port = media->get_port();
+    pj_strdup (_pool, &med->desc.transport, &STR_RTP_AVP);
 
-    status = pjmedia_sdp_validate( _localSDP );
-    if (status != PJ_SUCCESS) {
-        _debug("Can not generate valid local sdp\n");
-        return false;
-    }
+    // Media format ( RTP payload )
+    count = media->get_media_codec_list().size();
+    med->desc.fmt_count = count;
 
-    _debug("Before create negociator!\n");
-    status = pjmedia_sdp_neg_create_w_remote_offer(_pool, _localSDP, remote_sdp, &_negociator);
-    if (status != PJ_SUCCESS) {
-        _debug("Can not create negociator\n");
-        return false;
+    // add the payload list
+    for(i=0; i<count; i++){
+        codec = media->get_media_codec_list()[i];
+        tmp << codec->getPayload (); 
+        pj_strdup2( _pool, &med->desc.fmt[i], tmp.str().c_str());
+
+        // Add a rtpmap field for each codec
+        // We could add one only for dynamic payloads because the codecs with static RTP payloads
+        // are entirely defined in the RFC 3351, but if we want to add other attributes like an asymmetric
+        // connection, the rtpmap attribute will be useful to specify for which codec it is applicable
+        rtpmap.pt = med->desc.fmt[i];
+        rtpmap.enc_name = pj_str( (char*) codec->getCodecName().c_str() );
+        rtpmap.clock_rate = codec->getClockRate();
+        // Add the channel number only if different from 1
+        if( codec->getChannel() > 1 )
+            rtpmap.param = pj_str( (char*) codec->getChannel() );
+        else
+            rtpmap.param.slen = 0;
+        pjmedia_sdp_rtpmap_to_attr( _pool, &rtpmap, &attr );
+        med->attr[med->attr_count++] = attr;
     }
-    _debug("After create negociator!\n");
+    
+    // Add the direction stream
+    attr = (pjmedia_sdp_attr*)pj_pool_zalloc( _pool, sizeof(pjmedia_sdp_attr) );
+    pj_strdup2( _pool, &attr->name, media->get_stream_direction_str().c_str());
+    med->attr[ med->attr_count++] = attr;
 
-    pjmedia_sdp_media* remote_med = getRemoteMedia(remote_sdp);
-    if (remote_med == 0) {
-        _debug("SIP Failure: unable to get remote media\n");
-        return false;
-    }
+    *p_med = med;
+}
 
-    _debug("Before set audio!\n");
-    if (!setRemoteAudioFromSDP(remote_sdp, remote_med)) {
-        _debug("SIP Failure: unable to set IP address and port from SDP\n");
-        return false;
-    }
+int Sdp::create_local_offer (){
+    pj_status_t status;
 
-    _debug("Before set codec!\n");
-    if (!setAudioCodecFromSDP(remote_med)) {
-        _debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
-        return false;
-    }
+    // Build local media capabilities
+    set_local_media_capabilities ();
 
-    return true;
-}
+    // Reference: RFC 4566 [5]
 
-    bool
-Sdp::SIPCallAnsweredWithoutHold(pjsip_rx_data *rdata)
-{
-    pjmedia_sdp_session* remote_sdp = getRemoteSDPFromRequest(rdata);
-    if (remote_sdp == NULL) {
-        _debug("SIP Failure: no remote sdp\n");
-        return false;
-    }
+    /* Create and initialize basic SDP session */
+    this->_local_offer = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_session);
+    this->_local_offer->conn = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_conn);
 
-    pjmedia_sdp_media* remote_med = getRemoteMedia(remote_sdp);
-    if (remote_med==NULL) {
-        return false;
-    }
+    /* Initialize the fields of the struct */
+    sdp_add_protocol();
+    sdp_add_origin();
+    sdp_add_session_name();
+    sdp_add_connection_info();
+    sdp_add_timing();
+    //sdp_addAttributes( _pool );
+    sdp_add_media_description( );
 
-    _debug("Before set audio!\n");
-    if (!setRemoteAudioFromSDP(remote_sdp, remote_med)) {
-        _debug("SIP Failure: unable to set IP address and port from SDP\n");
-        return false;
-    }
+    // Validate the sdp session
+    status = pjmedia_sdp_validate( this->_local_offer );
+    if (status != PJ_SUCCESS)
+        return status;
+    return PJ_SUCCESS;
+}
 
-    _debug("Before set codec!\n");
-    if (!setAudioCodecFromSDP(remote_med)) {
-        _debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
-        return false;
-    }
 
-    return true;
-}
 
 
-    pjmedia_sdp_session* 
-Sdp::getRemoteSDPFromRequest(pjsip_rx_data *rdata)
-{
-    pjmedia_sdp_session *sdp;
-    pjsip_msg *msg;
-    pjsip_msg_body *body;
+int Sdp::create_initial_offer(  ){
+    pj_status_t status;
+    pjmedia_sdp_neg_state state;
 
-    msg = rdata->msg_info.msg;
-    body = msg->body;
+    // Build the SDP session descriptor
+    create_local_offer( );
 
-    pjmedia_sdp_parse( rdata->tp_info.pool, (char*)body->data, body->len, &sdp );
+    // Create the SDP negociator instance with local offer
+    status = pjmedia_sdp_neg_create_w_local_offer( _pool, get_local_sdp_session(), &_negociator);
+    state = pjmedia_sdp_neg_get_state( _negociator );
 
-    return sdp;
-}
+    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
 
-    bool 
-Sdp::setRemoteAudioFromSDP(pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media *remote_med)
-{
-    std::string remoteIP(remote_sdp->conn->addr.ptr, remote_sdp->conn->addr.slen);
-    _debug("            Remote Audio IP: %s\n", remoteIP.data());
-    setRemoteIP(remoteIP);
-    int remotePort = remote_med->desc.port; 
-    _debug("            Remote Audio Port: %d\n", remotePort);
-    setRemoteAudioPort(remotePort);
-
-    return true;
+    return PJ_SUCCESS;
 }
 
-    bool 
-Sdp::setAudioCodecFromSDP(pjmedia_sdp_media* remote_med)
-{
-    // Remote Payload
-    int payLoad = -1;
-    int codecCount = remote_med->desc.fmt_count;
-    for(int i = 0; i < codecCount; i++) {
-        payLoad = atoi(remote_med->desc.fmt[i].ptr);
-        if (_codecMap.isActive((AudioCodecType)payLoad))
-            break;
-
-        payLoad = -1;
-    }
+int Sdp::receiving_initial_offer( pjmedia_sdp_session* remote ){
+    // Create the SDP negociator instance by calling
+    // pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
+
+    pj_status_t status;
+    pjmedia_sdp_neg_state state;
 
-    if(payLoad != -1) {
-        _debug("            Payload: %d\n", payLoad);
-        setAudioCodec((AudioCodecType)payLoad);
-    } else
-        return false;
+    // Create the SDP negociator instance by calling
+    // pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
+
+    // Build the local offer to respond
+    create_local_offer(  );
+
+    status = pjmedia_sdp_neg_create_w_remote_offer( _pool,
+                                                    get_local_sdp_session(), remote, &_negociator );
+    state = pjmedia_sdp_neg_get_state( _negociator );
+    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
 
-    return true;
+    return PJ_SUCCESS;
 }
 
-void Sdp::sdpAddOrigin( void )
-{
+void Sdp::sdp_add_protocol( void ){
+    this->_local_offer->origin.version = 0;
+}
+
+void Sdp::sdp_add_origin( void ){
     pj_time_val tv;
     pj_gettimeofday(&tv);
 
-    _localSDP->origin.user = pj_str(pj_gethostname()->ptr);
+    this->_local_offer->origin.user = pj_str(pj_gethostname()->ptr);
     // Use Network Time Protocol format timestamp to ensure uniqueness.
-    _localSDP->origin.id = tv.sec + 2208988800UL;
+    this->_local_offer->origin.id = tv.sec + 2208988800UL;
     // The type of network ( IN for INternet )
-    _localSDP->origin.net_type = pj_str((char*)"IN"); //STR_IN;
+    this->_local_offer->origin.net_type = STR_IN;
     // The type of address
-    _localSDP->origin.addr_type = pj_str((char*)"IP4"); //STR_IP4;
+    this->_local_offer->origin.addr_type = STR_IP4;
     // The address of the machine from which the session was created
-    _localSDP->origin.addr = pj_str( (char*)_ipAddr.c_str() );    
+    this->_local_offer->origin.addr = pj_str( (char*)_ip_addr.c_str() );
 }
 
-void Sdp::sdpAddConnectionInfo( void )
-{
-    _localSDP->conn->net_type = _localSDP->origin.net_type;
-    _debug("IP : %s\n", _localSDP->origin.net_type.ptr );
-    _localSDP->conn->addr_type = _localSDP->origin.addr_type;
-    _debug("IP : %s\n", _localSDP->origin.addr_type.ptr );
-    _localSDP->conn->addr = _localSDP->origin.addr;
-    _debug("IP : %s\n", _localSDP->origin.addr.ptr );
-}
 
-void Sdp::sdpAddMediaDescription()
-{
 
 
-    pjmedia_sdp_media* med;
-    pjmedia_sdp_attr *attr;
-    pjmedia_sdp_rtpmap rtpMap;
-    //int nbMedia, i;
+void Sdp::sdp_add_session_name( void ){
+    this->_local_offer->name = STR_SDP_NAME;
+}
 
-    med = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_media);
-    //nbMedia = getSDPMediaList().size();
-    _localSDP->media_count = 1;
 
-    med->desc.media = pj_str((char*)"audio");
-    med->desc.port_count = 1;
-    med->desc.port = getLocalExternAudioPort();
-    med->desc.transport = pj_str((char*)"RTP/AVP");
+void Sdp::sdp_add_connection_info( void ){
+    this->_local_offer->conn->net_type = _local_offer->origin.net_type;
+    this->_local_offer->conn->addr_type = _local_offer->origin.addr_type;
+    this->_local_offer->conn->addr = _local_offer->origin.addr;
+}
 
-    CodecOrder::iterator itr;
 
-    itr = _codecMap.getActiveCodecs().begin();
-    int count = _codecMap.getActiveCodecs().size();
-    _debug ("Add media description %i\n", count);
-    med->desc.fmt_count = count;
+void Sdp::sdp_add_timing( void ){
+    // RFC 3264: An offer/answer model session description protocol
+    // As the session is created and destroyed through an external signaling mean (SIP), the line
+    // should have a value of "0 0".
 
-    int i = 0;
-
-    while(itr != _codecMap.getActiveCodecs().end()) {
-        _debug ("First media description\n");
-        std::ostringstream format;
-        format << *itr;
-        pj_strdup2(_pool, &med->desc.fmt[i], format.str().data());
-
-        rtpMap.pt = med->desc.fmt[i];
-        rtpMap.enc_name = pj_str((char *)_codecMap.getCodecName(*itr).data());
-        rtpMap.clock_rate = _codecMap.getSampleRate(*itr);
-        if(_codecMap.getChannel(*itr) > 1) {
-            std::ostringstream channel;
-            channel << _codecMap.getChannel(*itr);
-            rtpMap.param = pj_str((char *)channel.str().data());
-        } else
-            rtpMap.param.slen = 0;
-
-        pjmedia_sdp_rtpmap_to_attr( _pool, &rtpMap, &attr );
-        med->attr[i] = attr;
-        i++;
-        itr++;
-    }
+    this->_local_offer->time.start = this->_local_offer->time.stop = 0;
+}
 
-    //FIXME! Add the direction stream
-    attr = (pjmedia_sdp_attr*)pj_pool_zalloc( _pool, sizeof(pjmedia_sdp_attr) );
-    pj_strdup2( _pool, &attr->name, "sendrecv");
-    med->attr[ i++] = attr;
-    med->attr_count = i;
+void Sdp::sdp_add_attributes( ){
+    pjmedia_sdp_attr *a;
+    this->_local_offer->attr_count = 1;
+    a =  PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_attr);
+    a->name=STR_SENDRECV;
+    _local_offer->attr[0] = a;
+}
 
-    _localSDP->media[0] = med;
-    /*for( i=0; i<nbMedia; i++ ){
-      getMediaDescriptorLine( getSDPMediaList()[i], pool, &med );
-      this->_local_offer->media[i] = med;
-      } */
 
-}
+void Sdp::sdp_add_media_description( ){
+    pjmedia_sdp_media* med;
+    int nb_media, i;
 
-pjmedia_sdp_media* Sdp::getRemoteMedia(pjmedia_sdp_session *remote_sdp)
-{
-    int count, i;
+    med = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_media);
+    nb_media = get_local_media_cap().size();
+    this->_local_offer->media_count = nb_media;
 
-    count = remote_sdp->media_count;
-    for(i = 0; i < count; ++i) {
-        if(pj_stricmp2(&remote_sdp->media[i]->desc.media, "audio") == 0)
-            return remote_sdp->media[i];
+    for( i=0; i<nb_media; i++ ){
+        set_media_descriptor_line( get_local_media_cap()[i], &med );
+        this->_local_offer->media[i] = med;
     }
-
-    return NULL;
 }
 
-bool Sdp::startNegociation()
-{
-    pj_status_t status;
-    _debug("Before negotiate!\n");
-    status = pjmedia_sdp_neg_negotiate(_pool, _negociator, 0);
 
-    return (status == PJ_SUCCESS);
-}
- 
-bool Sdp::createLocalOffer (void) {
-    pj_status_t status;
+std::string Sdp::media_to_string( void ){
+    int size, i;
+    std::ostringstream res;
 
-    // Have to do some stuff here with the SDP
-    _localSDP = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_session);
-    _localSDP->conn =  PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_conn);
-
-    _localSDP->origin.version = 0;
-    sdpAddOrigin();
-    _localSDP->name = pj_str((char*)"sflphone");
-    sdpAddConnectionInfo();
-    _localSDP->time.start = _localSDP->time.stop = 0;
-    sdpAddMediaDescription();
-
-    _debug("Before validate SDP!\n");
-    status = pjmedia_sdp_validate( _localSDP );
-    if (status != PJ_SUCCESS) {
-        _debug("Can not generate valid local sdp %d\n", status);
-        return false;
+    size = _local_media_cap.size();
+    for( i = 0; i < size ; i++ ){
+        res << _local_media_cap[i]->to_string();
     }
 
- 
-
+    res << std::endl;
+    return res.str();
 }
-bool Sdp::createInitialOffer()
-{
-
-    pj_status_t status;
-
-    createLocalOffer ();
-
-   _debug("Before create negociator!\n");
-    // Create the SDP negociator instance with local offer
-    status = pjmedia_sdp_neg_create_w_local_offer( _pool, _localSDP, &_negociator);
-    //state = pjmedia_sdp_neg_get_state( _negociator );
-
-    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
-
-    return true;
 
+void Sdp::clean_session_media(){
+    _session_media.clear();
 }
 
-int Sdp::receiving_initial_offer( pjmedia_sdp_session* remote )
-{
-    // Create the SDP negociator instance by calling
-    // pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
-
-    pj_status_t status;
-    pjmedia_sdp_neg_state state;
+void Sdp::set_negociated_offer( const pjmedia_sdp_session *sdp ){
 
-    // Create the SDP negociator instance by calling
-    // pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
+    int nb_media, nb_codecs;
+    int i,j, port;
+    pjmedia_sdp_media *current;
+    sdpMedia *media;
+    std::string type, dir;
+    CodecsMap codecs_list;
+    CodecsMap::iterator iter;
+    AudioCodec *codec_to_add;
 
-    // Build the local offer to respond
-    createLocalOffer();
+    _negociated_offer = (pjmedia_sdp_session*)sdp;
+    
+    codecs_list = Manager::instance().getCodecDescriptorMap().getCodecsMap();
+
+    // retrieve the media information
+    nb_media = _negociated_offer->media_count;
+    for( i=0; i<nb_media ; i++ ){
+        // Retrieve the media 
+        current = _negociated_offer->media[i];
+        type = current->desc.media.ptr;
+        port = current->desc.port;
+        media = new sdpMedia( type, port );
+        // Retrieve the payload
+        nb_codecs = current->desc.fmt_count;  // Must be one
+        for( j=0 ; j<nb_codecs ; j++ ){
+            iter = codecs_list.find((AudioCodecType)atoi(current->desc.fmt[j].ptr));  
+            if (iter==codecs_list.end())
+                return;
+            media->add_codec(iter->second);
+        }
+        _session_media.push_back(media);
+    }
+}
 
-    status = pjmedia_sdp_neg_create_w_remote_offer( _pool,
-            getLocalSDPSession(), remote, &_negociator );
-    state = pjmedia_sdp_neg_get_state( _negociator );
-    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
+AudioCodec* Sdp::get_session_media( void ){
 
-    return PJ_SUCCESS;
+    int nb_media;
+    int nb_codec;
 
+    nb_media = _session_media.size();
+    nb_codec = _session_media[0]->get_media_codec_list().size();
 
+    return _session_media[0]->get_media_codec_list()[0];
 }
 
+
 void Sdp::toString (void) {
 
     std::ostringstream sdp;
 
-    sdp <<  "origin= " <<  _localSDP->origin.user.ptr << "\n";
-    sdp << "origin.id= " << _localSDP->origin.id << "\n";
-    sdp << "origin.version= " << _localSDP->origin.version<< "\n";
-    sdp << "origin.net_type= " << _localSDP->origin.net_type.ptr<< "\n";
-    sdp << "origin.addr_type= " << _localSDP->origin.addr_type.ptr<< "\n";
+    sdp <<  "origin= " <<  _local_offer->origin.user.ptr << "\n";
+    sdp << "origin.id= " << _local_offer->origin.id << "\n";
+    sdp << "origin.version= " << _local_offer->origin.version<< "\n";
+    sdp << "origin.net_type= " << _local_offer->origin.net_type.ptr<< "\n";
+    sdp << "origin.addr_type= " << _local_offer->origin.addr_type.ptr<< "\n";
 
-    sdp << "name=" << _localSDP->name.ptr<< "\n";
+    sdp << "name=" << _local_offer->name.ptr<< "\n";
 
-    sdp << "conn.net_type=" << _localSDP->conn->net_type.ptr<< "\n";
-    sdp << "conn.addr_type=" << _localSDP->conn->addr_type.ptr<< "\n";
-    sdp << "conn.addr=" << _localSDP->conn->addr.ptr<< "\n";
+    sdp << "conn.net_type=" << _local_offer->conn->net_type.ptr<< "\n";
+    sdp << "conn.addr_type=" << _local_offer->conn->addr_type.ptr<< "\n";
+    sdp << "conn.addr=" << _local_offer->conn->addr.ptr<< "\n";
 
-    sdp << "start=" <<_localSDP->time.start<< "\n";
-    sdp << "stop=" <<_localSDP->time.stop<< "\n";
+    sdp << "start=" <<_local_offer->time.start<< "\n";
+    sdp << "stop=" <<_local_offer->time.stop<< "\n";
 
-    sdp << "attr_count=" << _localSDP->attr_count << "\n";
-    sdp << "media_count=" << _localSDP->media_count << "\n";
-    sdp << "m=" << _localSDP->media[0]->desc.media.ptr << "\n";
-    sdp << "port=" << _localSDP->media[0]->desc.port << "\n";
-    sdp << "transport=" << _localSDP->media[0]->desc.transport.ptr << "\n";
-    sdp << "fmt_count=" << _localSDP->media[0]->desc.fmt_count << "\n";
-    sdp << "fmt=" << _localSDP->media[0]->desc.fmt[0].ptr << "\n";
+    sdp << "attr_count=" << _local_offer->attr_count << "\n";
+    sdp << "media_count=" << _local_offer->media_count << "\n";
+    sdp << "m=" << _local_offer->media[0]->desc.media.ptr << "\n";
+    sdp << "port=" << _local_offer->media[0]->desc.port << "\n";
+    sdp << "transport=" << _local_offer->media[0]->desc.transport.ptr << "\n";
+    sdp << "fmt_count=" << _local_offer->media[0]->desc.fmt_count << "\n";
+    sdp << "fmt=" << _local_offer->media[0]->desc.fmt[0].ptr << "\n";
+    
+    _debug ("LOCAL SDP: \n%s\n", sdp.str().c_str());
+
+}
+
+void Sdp::set_local_media_capabilities () {
+    
+    CodecOrder selected_codecs;
+    int i;
+    sdpMedia *audio;
+    CodecsMap codecs_list;
+    CodecsMap::iterator iter;
+    AudioCodec *codec_to_add;
+
+    /* Only one audio media used right now */
+    audio = new sdpMedia(MIME_TYPE_AUDIO);
+    
+    /* We retrieve the codecs selected by the user */
+    selected_codecs = Manager::instance().getCodecDescriptorMap().getActiveCodecs(); 
+    codecs_list = Manager::instance().getCodecDescriptorMap().getCodecsMap();
+    for (i=0; i<selected_codecs.size(); i++){
+        iter = codecs_list.find(selected_codecs[i]);  
     
-    //_debug ("LOCAL SDP: \n%s\n", sdp.str().c_str());
+        if (iter==codecs_list.end())
+            return;
 
+        audio->add_codec (iter->second);
+    } 
 }
diff --git a/src/sdp.h b/src/sdp.h
index 99d96ba7ac058e135ba1925d074970ad9edeed8e..4b846dce2e980aba3095a58a8fe4f7d1df4cfe1d 100644
--- a/src/sdp.h
+++ b/src/sdp.h
@@ -29,74 +29,125 @@
 #include <pj/assert.h>
 
 #include "audio/codecDescriptor.h"
+#include "sdpmedia.h"
 
 class Sdp {
 
     public:
-
+        
+        /*
+         * Class Constructor.
+         *
+         * @param ip_addr
+         */
         Sdp(pj_pool_t *pool);
 
+        /* Class destructor */
         ~Sdp();
 
-        /**
-         * Setup incoming call, and verify for errors, before ringing the user.
-         * @param pjsip_rx_data *rdata
-         * @param pj_pool_t *pool
-         * @return bool True on success
-         *		    false otherwise
+        /*
+         * Read accessor. Get the list of the local media capabilities. 
+         *
+         * @return std::vector<sdpMedia*>   the vector containing the different media
          */
-        bool SIPCallInvite(pjsip_rx_data *rdata);
+        std::vector<sdpMedia*> get_local_media_cap( void ) { return _local_media_cap; }
 
-        bool SIPCallAnsweredWithoutHold(pjsip_rx_data *rdata);
+        void set_local_media_cap (void);
 
-        /**
-         * Get the local SDP 
-         * @param void
-         * @return _localSDP pjmedia_sdp_session
+         /*
+         *  Read accessor. Get the sdp session information
+         *
+         *  @return pjmedia_sdp_session   The structure that describes a SDP session
          */
-        pjmedia_sdp_session* getLocalSDPSession( void ) { return _localSDP; }
+        pjmedia_sdp_session* get_local_sdp_session( void ) { return _local_offer; }
 
-        /**
-         * Begin negociation of media information between caller and callee
-         * @param pj_pool_t *pool
-         * @return bool True if ok
+        /*
+         * Write accessor. Set the local IP address that will be used in the sdp session
          */
-        bool startNegociation();
+        void set_ip_address( std::string ip_addr ) { _ip_addr = ip_addr; }
 
-        /**
-         * Create the localSDP, media negociation and codec information
-         * @param pj_pool_t *pool
-         * @return void
+        /*
+         * Read accessor. Get the local IP address
+         */
+        std::string get_ip_address( void ) { return _ip_addr; }
+        
+        /*
+         * Build the local SDP offer
+         */
+        int create_local_offer( );
+
+        /*
+         * Build the sdp media section
+         * Add rtpmap field if necessary
+         *
+         * @param media     The media to add to SDP
+         * @param med   The structure to receive the media section
          */
-        bool createInitialOffer();
+        void set_media_descriptor_line( sdpMedia* media, pjmedia_sdp_media** p_med );
 
-        bool createLocalOffer ();
+        /*
+         * On building an invite outside a dialog, build the local offer and create the
+         * SDP negociator instance with it.
+         */
+        int create_initial_offer( );
 
-        /** 
-         * Set internal codec Map: initialization only, not protected 
-         * @param map The codec map
+         /*
+         * On receiving an invite outside a dialog, build the local offer and create the
+         * SDP negociator instance with the remote offer.
+         *
+         * @param remote    The remote offer
+         */
+        int receiving_initial_offer( pjmedia_sdp_session* remote );
+        
+        /*
+         * Remove all media in the session media vector.
          */
-        void setCodecMap(const CodecDescriptor& map) { _codecMap = map; } 
+        void clean_session_media();
 
-        /**
-         * Save IP Address
-         * @param ip std::string 
-         * @return void
+        /*
+         * Return a string description of the media added to the session,
+         * ie the local media capabilities
          */
-        void setIp(std::string ip) {_ipAddr = ip;}
+        std::string media_to_string( void );
 
-        /** 
-         * Get internal codec Map: initialization only, not protected 
-         * @return CodecDescriptor	The codec map
+        /*
+         * Return the codec of the first media after negociation
+         */
+        AudioCodec* get_session_media( void );
+
+        /*
+         * read accessor. Return the negociated offer
+         *
+         * @return pjmedia_sdp_session  The negociated offer
+         */
+        pjmedia_sdp_session* get_negociated_offer( void ){
+            return _negociated_offer;
+        }
+
+         /*
+         * Start the sdp negociation.
+         *
+         * @return pj_status_t  0 on success
+         *                      1 otherwise
          */
-        CodecDescriptor& getCodecMap(){ return _codecMap; }
+        pj_status_t start_negociation( void ){
+            return pjmedia_sdp_neg_negotiate(
+                       _pool, _negociator, 0);
+        }
+
+         /*
+         * Retrieve the negociated sdp offer from the sip payload.
+         *
+         * @param sdp   the negociated offer
+         */
+        void set_negociated_offer( const pjmedia_sdp_session *sdp );
+
 
+  ///////////////////////////////////////////////////////////////////////////33
         void  setLocalExternAudioPort(int port){ _localPort = port; }
 
         int  getLocalExternAudioPort (void){ return _localPort; }
 
-        int receiving_initial_offer( pjmedia_sdp_session* remote );
-
         void toString (void);
 
         AudioCodecType getAudioCodec (void) { return _audioCodec; }
@@ -125,6 +176,7 @@ class Sdp {
          */
         const std::string& getRemoteIp() { return _remoteIPAddress; }
 
+        /////////////////////////////////////////////////////////////////////////
 
     private:
         /** 
@@ -133,74 +185,124 @@ class Sdp {
          */
         void setAudioCodec(AudioCodecType audioCodec) { _audioCodec = audioCodec; }
 
-        /** Codec pointer */
-        AudioCodecType _audioCodec;
+        /** Codec Map */
+        std::vector<sdpMedia*> _local_media_cap;
+
+        /* The media that will be used by the session (after the SDP negociation) */
+        std::vector<sdpMedia*> _session_media;
+
+        /** negociator */
+        pjmedia_sdp_neg *_negociator;
 
         /** IP address */
-        std::string _ipAddr;
+        std::string _ip_addr;
 
-        int _localPort;
+        /** Local SDP */
+        pjmedia_sdp_session *_local_offer;
 
-        /** Remote's IP address */
-        std::string  _remoteIPAddress;
+        /* The negociated SDP offer */
+        // Explanation: each endpoint's offer is negociated, and a new sdp offer results from this
+        // negociation, with the compatible media from each part 
+        pjmedia_sdp_session *_negociated_offer;
 
-        /** Remote's audio port */
-        unsigned int _remoteAudioPort;
+        // The pool to allocate memory
+        pj_pool_t *_pool;
+
+        Sdp(const Sdp&); //No Copy Constructor
+        Sdp& operator=(const Sdp&); //No Assignment Operator
 
+        void set_local_media_capabilities ();
 
-        /**
-         * Get a valid remote media
-         * @param remote_sdp pjmedia_sdp_session*
-         * @return pjmedia_sdp_media*. A valid sdp_media_t or 0
+        /*
+         *  Mandatory field: Origin ("o=")
+         *  Gives the originator of the session.
+         *  Serves as a globally unique identifier for this version of this session description.
          */
-        pjmedia_sdp_media* getRemoteMedia(pjmedia_sdp_session *remote_sdp);
+        void sdp_add_origin( void );
 
-        pjmedia_sdp_session * getRemoteSDPFromRequest (pjsip_rx_data *rdata);
+        /*
+         *  Mandatory field: Protocol version ("v=")
+         *  Add the protocol version in the SDP session description
+         */
+        void sdp_add_protocol( void );
 
-        /**
-         * Set Audio Port and Audio IP from Remote SDP Info
-         * @param remote_med Remote Media info
-         * @param remote_sdp Remote SDP pointer
-         * @return bool True if everything is set correctly
+        /*
+         *  Optional field: Connection data ("c=")
+         *  Contains connection data.
+         */
+        void sdp_add_connection_info( void );
+        
+        /*
+         *  Mandatory field: Session name ("s=")
+         *  Add a textual session name.
          */
-        bool setRemoteAudioFromSDP(pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media* remote_med);
+        void sdp_add_session_name( void );
 
-        /**
-         * Set Audio Codec with the remote choice
-         * @param remote_med Remote Media info
-         * @return bool True if everything is set correctly
+        /*
+         *  Optional field: Session information ("s=")
+         *  Provides textual information about the session.
          */
-        bool setAudioCodecFromSDP(pjmedia_sdp_media* remote_med);
+        void sdp_add_session_info( void ){}
 
-        /** Local SDP */
-        pjmedia_sdp_session *_localSDP;
-        pjmedia_sdp_session *_negociated_offer;
+        /*
+         *  Optional field: Uri ("u=")
+         *  Add a pointer to additional information about the session.
+         */
+        void sdp_add_uri( void ) {}
 
-        /** negociator */
-        pjmedia_sdp_neg *_negociator;
+        /*
+         *  Optional fields: Email address and phone number ("e=" and "p=")
+         *  Add contact information for the person responsible for the conference.
+         */
+        void sdp_add_email( void ) {}
 
-        // The pool to allocate memory
-        pj_pool_t *_pool;
+        /*
+         *  Optional field: Bandwidth ("b=")
+         *  Denotes the proposed bandwidth to be used by the session or the media .
+         */
+        void sdp_add_bandwidth( void ) {}
 
-        /** Codec Map */
-        CodecDescriptor _codecMap;
+        /*
+         *  Mandatory field: Timing ("t=")
+         *  Specify the start and the stop time for a session.
+         */
+        void sdp_add_timing( void );
 
-        /**
-         * Set origin information for local SDP
+        /*
+         * Optional field: Time zones ("z=")
          */
-        void sdpAddOrigin( void );
+        void sdp_add_time_zone( void ) {}
 
-        /**
-         * Set connection information for local SDP
+        /*
+         * Optional field: Encryption keys ("k=")
          */
-        void sdpAddConnectionInfo( void );
-        /**
-         * Set media information including codec for localSDP
-         * @param  pj_pool_t* pool
-         * @return void
+        void sdp_add_encryption_key( void ) {}
+
+        /*
+         * Optional field: Attributes ("a=")
+         */
+        void sdp_add_attributes( );
+
+        /*
+         * Mandatory field: Media descriptions ("m=")
          */
-        void sdpAddMediaDescription();
+        void sdp_add_media_description();
+
+
+//////////////////////////////////////////////////////////////////3
+        /** Codec pointer */
+        AudioCodecType _audioCodec;
+
+        int _localPort;
+
+        /** Remote's IP address */
+        std::string  _remoteIPAddress;
+
+        /** Remote's audio port */
+        unsigned int _remoteAudioPort;
 
+////////////////////////////////////////////////////////////////////
+              
 };
 
 
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index a1fec949673df9f2ae270c6031a46a987574ee7f..90f607801039886d34b68b99f7470b138f03b6a5 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -29,6 +29,14 @@
 
 /**************** EXTERN VARIABLES AND FUNCTIONS (callbacks) **************************/
 
+/*
+ * Retrieve the SDP of the peer contained in the offer
+ *
+ * @param rdata The request data
+ * @param r_sdp The pjmedia_sdp_media to stock the remote SDP
+ */
+void get_remote_sdp_from_offer( pjsip_rx_data *rdata, pjmedia_sdp_session** r_sdp );
+
 int getModId();
 
 /*
@@ -250,6 +258,21 @@ SIPVoIPLink::terminateOneCall(const CallID& id)
     }
 }
 
+void get_remote_sdp_from_offer( pjsip_rx_data *rdata, pjmedia_sdp_session** r_sdp ){
+    pjmedia_sdp_session *sdp;
+    pjsip_msg *msg;
+    pjsip_msg_body *body;
+
+    // Get the message
+    msg = rdata->msg_info.msg;
+    // Get the body message
+    body = msg->body;
+
+    // Parse the remote request to get the sdp session
+    pjmedia_sdp_parse( rdata->tp_info.pool, (char*)body->data, body->len, &sdp );
+
+    *r_sdp = sdp;
+}
 
 
     void
@@ -267,7 +290,7 @@ SIPVoIPLink::getEvent()
 
 int SIPVoIPLink::sendRegister( AccountID id )
 {
-  _debug("sendRegister called!!!!!!!!!!!!!!!!!!!!!!! \n");
+    _debug("sendRegister called!!!!!!!!!!!!!!!!!!!!!!! \n");
     pj_status_t status;
     int expire_value;
     char contactTmp[256];
@@ -425,14 +448,16 @@ SIPVoIPLink::newOutgoingCall(const CallID& id, const std::string& toUrl)
             delete call; call=0;
             return call;
         }
-        //call->setPeerNumber(toUrl);
+
         call->setPeerNumber(getSipTo(toUrl, account->getHostname()));
-      
+
         call->initRecFileName();
 
         _debug("Try to make a call to: %s with call ID: %s\n", toUrl.data(), id.data());
-        // we have to add the codec before using it in SIPOutgoingInvite...
-        call->getLocalSDP()->setCodecMap(Manager::instance().getCodecDescriptorMap());
+        // Building the local SDP offer
+        call->getLocalSDP()->set_ip_address(getLocalIP());
+        call->getLocalSDP()->create_initial_offer();
+
         if ( SIPOutgoingInvite(call) ) {
             call->setConnectionState(Call::Progressing);
             call->setState(Call::Active);
@@ -463,7 +488,7 @@ SIPVoIPLink::answer(const CallID& id)
     }
 
     // User answered the incoming call, tell peer this news
-    if (call->getLocalSDP()->startNegociation()) {
+    if (call->getLocalSDP()->start_negociation()) {
         // Create and send a 200(OK) response
         _debug("SIPVoIPLink::answer:UserAgent: Negociation success! : call %s \n", call->getCallId().c_str());
         status = pjsip_inv_answer(call->getInvSession(), PJSIP_SC_OK, NULL, NULL, &tdata);
@@ -581,9 +606,6 @@ SIPVoIPLink::onhold(const CallID& id)
 {
 
     pj_status_t status;
-    pjsip_tx_data *tdata;
-    pjmedia_sdp_attr *attr;
-    pjmedia_sdp_session* local_sdp;
     SIPCall* call;
 
     call = getSIPCall(id);
@@ -595,43 +617,54 @@ SIPVoIPLink::onhold(const CallID& id)
     call->setAudioStart(false);
     call->setState(Call::Hold);
     _debug("* SIP Info: Stopping AudioRTP for onhold action\n");
-    //_mutexSIP.enterMutex();
     _audiortp->closeRtpSession();
-    //_mutexSIP.leaveMutex();
 
-    local_sdp = call->getLocalSDP()->getLocalSDPSession();
+    /* Create re-INVITE with new offer */
+    status = inv_session_reinvite (call, "sendonly");
+
+    return (status == PJ_SUCCESS);
+}
+
+int SIPVoIPLink::inv_session_reinvite (SIPCall *call, std::string direction) {
+
+    pj_status_t status;
+    pjsip_tx_data *tdata;
+    pjmedia_sdp_session *local_sdp;
+    pjmedia_sdp_attr *attr;
+
+    local_sdp = call->getLocalSDP()->get_local_sdp_session();
 
     if( local_sdp == NULL ){
         _debug("! SIP Failure: unable to find local_sdp\n");
         return false;
     }
 
-    /* Create re-INVITE with new offer */
-    // Remove all the attributes with the specified name
+    // reinvite only if connected
+    // Build the local SDP offer
+    status = call->getLocalSDP()->create_initial_offer( );
     pjmedia_sdp_media_remove_all_attr(local_sdp->media[0], "sendrecv");
     attr = pjmedia_sdp_attr_create(_pool, "sendonly", NULL);
     pjmedia_sdp_media_add_attr(local_sdp->media[0], attr);
+    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
 
-    status = pjsip_inv_reinvite( call->getInvSession(), NULL, local_sdp, &tdata);
-    if( status != PJ_SUCCESS )
-    {
-        _debug("On hold: creation of the Re-invite request failed\n");
-        return false;
-    }
-    /* Send the request */
-    status = pjsip_inv_send_msg( call->getInvSession(), tdata);
+    // Build the reinvite request
+    status = pjsip_inv_reinvite( call->getInvSession(), NULL,
+            local_sdp, &tdata );
+    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
 
-    return (status == PJ_SUCCESS);
+    // Send it
+    status = pjsip_inv_send_msg( call->getInvSession(), tdata );
+    PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
+
+    return PJ_SUCCESS;
 }
 
+
     bool 
 SIPVoIPLink::offhold(const CallID& id)
 {
     SIPCall *call;
     pj_status_t status;
-    pjsip_tx_data *tdata;
-    pjmedia_sdp_attr *attr;
-    pjmedia_sdp_session* local_sdp;
 
     call = getSIPCall(id);
 
@@ -640,28 +673,9 @@ SIPVoIPLink::offhold(const CallID& id)
         return false; 
     }
 
-    local_sdp = call->getLocalSDP()->getLocalSDPSession();
-    if( local_sdp == NULL ){
-        _debug("! SIP Failure: unable to find local_sdp\n");
-        return false;
-    }
-
     /* Create re-INVITE with new offer */
-    // Remove all the attributes with the specified name
-    pjmedia_sdp_media_remove_all_attr(local_sdp->media[0], "sendonly");
-    attr = pjmedia_sdp_attr_create(_pool, "sendrecv", NULL);
-    pjmedia_sdp_media_add_attr(local_sdp->media[0], attr);
-
-    status = pjsip_inv_reinvite( call->getInvSession(), NULL, local_sdp , &tdata);
-    if( status != PJ_SUCCESS )
-    {
-        _debug("Off hold: creation of the Re-invite request failed\n");
-        return false;
-    }
-
-    /* Send the request */
-    status = pjsip_inv_send_msg( call->getInvSession(), tdata);
-    if( status != PJ_SUCCESS )
+    status = inv_session_reinvite (call, "sendonly");
+    if (status != PJ_SUCCESS)
         return false;
 
     // Enable audio
@@ -808,15 +822,15 @@ SIPVoIPLink::isRecording(const CallID& id)
 }
 
 
-std::string 
+    std::string 
 SIPVoIPLink::getCurrentCodecName()
 {
 
-  SIPCall *call = getSIPCall(Manager::instance().getCurrentCallId());  
+    SIPCall *call = getSIPCall(Manager::instance().getCurrentCallId());  
 
-  AudioCodec *ac = call->getLocalSDP()->getCodecMap().getCodec(call->getLocalSDP()->getAudioCodec());
+    AudioCodec *ac = call->getLocalSDP()->get_session_media();
 
-  return ac->getCodecName();
+    return ac->getCodecName();
 }
 
     bool 
@@ -927,16 +941,10 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject UNUSED)
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, false);
 
     setCallAudioLocal(call, getLocalIPAddress(), useStun(), getStunServer());
-    call->getLocalSDP()->setIp(getLocalIP());
-
-    // Building the local SDP offer
-    call->getLocalSDP()->createInitialOffer();
-
-    call->getLocalSDP()->toString ();
 
     // Create the invite session for this call
     pjsip_inv_session *inv;
-    status = pjsip_inv_create_uac(dialog, call->getLocalSDP()->getLocalSDPSession(), 0, &inv);
+    status = pjsip_inv_create_uac(dialog, call->getLocalSDP()->get_local_sdp_session(), 0, &inv);
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, false);
 
     // Set auth information
@@ -1082,7 +1090,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
 
             if (call->getConnectionState() != Call::Connected) {
                 //call->SIPCallAnswered(event);
-                call->getLocalSDP()->SIPCallAnsweredWithoutHold(rdata);
+                //call->getLocalSDP()->SIPCallAnsweredWithoutHold(rdata);
 
                 call->setConnectionState(Call::Connected);
                 call->setState(Call::Active);
@@ -1103,8 +1111,8 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
         }
 
 
-SIPCall*
-SIPVoIPLink::getSIPCall(const CallID& id) 
+    SIPCall*
+        SIPVoIPLink::getSIPCall(const CallID& id) 
         {
             Call* call = getCall(id);
             if (call) {
@@ -1114,9 +1122,9 @@ SIPVoIPLink::getSIPCall(const CallID& id)
         }
 
 
-void SIPVoIPLink::setStunServer( const std::string &server )
-{
-         if(server != "") {
+    void SIPVoIPLink::setStunServer( const std::string &server )
+    {
+        if(server != "") {
 
             useStun(true);
             _stunServer = server;
@@ -1353,8 +1361,8 @@ void SIPVoIPLink::setStunServer( const std::string &server )
 
         // Init bound address to ANY
         pj_memset(&bound_addr, 0, sizeof (bound_addr));
-        
-       
+
+
         bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY);
         bound_addr.sin_port = pj_htons((pj_uint16_t) _localPort);
         bound_addr.sin_family = PJ_AF_INET;
@@ -1364,10 +1372,10 @@ void SIPVoIPLink::setStunServer( const std::string &server )
 
         _debug("bound_addr.sin_port %i \n", bound_addr.sin_port);
 
-        
+
         _debug("UserAgent: Use IP: %s\n", _localExternAddress.data());
-        
-        
+
+
         // Create UDP-Server (default port: 5060)
         strcpy(tmpIP, _localExternAddress.data());
         pj_strdup2(_pool, &a_name.host, tmpIP);
@@ -1573,6 +1581,17 @@ void SIPVoIPLink::setStunServer( const std::string &server )
 
     void call_on_media_update( pjsip_inv_session *inv UNUSED, pj_status_t status UNUSED) {
         _debug("call_on_media_updated\n");
+
+        const pjmedia_sdp_session *r_sdp;
+
+        if (status != PJ_SUCCESS) {
+            return;
+        }
+
+        // Get the new sdp, result of the negociation
+        pjmedia_sdp_neg_get_active_local( inv->neg, &r_sdp );
+
+        // Clean the resulting sdp offer to create a new one (in case of a reinvite)
     }
 
     void call_on_forked(pjsip_inv_session *inv, pjsip_event *e){
@@ -1768,6 +1787,8 @@ void SIPVoIPLink::setStunServer( const std::string &server )
             SIPVoIPLink *link;
             CallID id;
             SIPCall* call;
+            pjsip_inv_session *inv;
+            pjmedia_sdp_session *r_sdp;
 
             // voicemail part
             std::string method_name;
@@ -1862,43 +1883,33 @@ void SIPVoIPLink::setStunServer( const std::string &server )
                 return false;
             }
 
+            // Have to do some stuff with the SDP
+            // We retrieve the remote sdp offer in the rdata struct to begin the negociation
+            call->getLocalSDP()->set_ip_address(link->getLocalIPAddress());
+            get_remote_sdp_from_offer( rdata, &r_sdp );
+            call->getLocalSDP()->receiving_initial_offer( r_sdp );
+
             // Set the codec map, IP, peer number and so on... for the SIPCall object
             setCallAudioLocal(call, link->getLocalIPAddress(), link->useStun(), link->getStunServer());
-            call->getLocalSDP()->setCodecMap(Manager::instance().getCodecDescriptorMap());
+
             call->setConnectionState(Call::Progressing);
-            call->getLocalSDP()->setIp(link->getLocalIPAddress());
             call->setPeerNumber(peerNumber);
 
             call->initRecFileName();
 
-            /* Call the SIPCallInvite function to generate the local sdp,
-             * remote sdp and negociator.
-             * This function is also used to set the parameters of audio RTP, including:
-             *     local IP and port number 
-             *     remote IP and port number
-             *     possilbe audio codec will be used in this call
-             */
-            if (call->getLocalSDP()->SIPCallInvite(rdata)) {
-
-                // Notify UI there is an incoming call
-                if (Manager::instance().incomingCall(call, account_id)) {
-                    // Add this call to the callAccountMap in ManagerImpl
-                    Manager::instance().getAccountLink(account_id)->addCall(call);
-                } else {
-                    // Fail to notify UI
-                    delete call;
-                    call = NULL;
-                    _debug("UserAgent: Fail to notify UI!\n");
-                    return false;
-                }
+            // Notify UI there is an incoming call
+            if (Manager::instance().incomingCall(call, account_id)) {
+                // Add this call to the callAccountMap in ManagerImpl
+                Manager::instance().getAccountLink(account_id)->addCall(call);
             } else {
-                // Fail to collect call information
+                // Fail to notify UI
                 delete call;
                 call = NULL;
-                _debug("UserAgent: Call SIPCallInvite failed!\n");
+                _debug("UserAgent: Fail to notify UI!\n");
                 return false;
             }
 
+
             /* Create the local dialog (UAS) */
             status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dialog);
             if (status != PJ_SUCCESS) {
@@ -1908,8 +1919,7 @@ void SIPVoIPLink::setStunServer( const std::string &server )
             }
 
             // Specify media capability during invite session creation
-            pjsip_inv_session *inv;
-            status = pjsip_inv_create_uas(dialog, rdata, call->getLocalSDP()->getLocalSDPSession(), 0, &inv);
+            status = pjsip_inv_create_uas(dialog, rdata, call->getLocalSDP()->get_local_sdp_session(), 0, &inv);
             PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
 
             // Associate the call in the invite session
@@ -2324,19 +2334,18 @@ void SIPVoIPLink::setStunServer( const std::string &server )
     void on_rx_offer( pjsip_inv_session *inv, const pjmedia_sdp_session *offer ){
 
 #ifdef CAN_REINVITE
-            
-            _debug ("reinvite                                                  SIP\n");
+        _debug ("reinvite                                                  SIP\n");
 
-            SIPCall *call;
-            pj_status_t status;
-                
-            call = (SIPCall*)inv->mod_data[getModId()];
-            if (!call)
-                return;
+        SIPCall *call;
+        pj_status_t status;
+
+        call = (SIPCall*)inv->mod_data[getModId()];
+        if (!call)
+            return;
 
-            call->getLocalSDP()->receiving_initial_offer( (pjmedia_sdp_session*)offer);
-            _debug("audio codec stté dans l'objet call: %i\n", call->getLocalSDP()->getAudioCodec());
-            status=pjsip_inv_set_sdp_answer( call->getInvSession(), call->getLocalSDP()->getLocalSDPSession() );
+        call->getLocalSDP()->receiving_initial_offer( (pjmedia_sdp_session*)offer);
+        _debug("audio codec setté dans l'objet call: %i\n", call->getLocalSDP()->getAudioCodec());
+        status=pjsip_inv_set_sdp_answer( call->getInvSession(), call->getLocalSDP()->get_local_sdp_session() );
 #endif
 
     }
diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h
index 8790b84d1415a94cb7c1cd855f0108e764c2f3e5..597ec1c32794b9f142d13f978a6f98d136b9d65f 100644
--- a/src/sipvoiplink.h
+++ b/src/sipvoiplink.h
@@ -303,6 +303,8 @@ class SIPVoIPLink : public VoIPLink
          */
          std::string getCurrentCodecName();
       
+        int inv_session_reinvite (SIPCall *call, std::string direction="");
+        
 
     private:
         /**
diff --git a/src/user_cfg.h b/src/user_cfg.h
index fea650490eb60e5e34d77339b086c5610442ab47..a5ab0625f91101b9fa943d9bddef934b4049ecfb 100644
--- a/src/user_cfg.h
+++ b/src/user_cfg.h
@@ -45,8 +45,6 @@
 #define VOLUME_MICRO		"Volume.micro"	      /** Mic volume */
 #define RECORD_PATH             "Record.path"          /** Recording path */
 
-#define VIDEO			"Video"		      /** Section Video */
-
 #define PREFERENCES		"Preferences"		  /** Section Preferences */
 #define CONFIG_DIALPAD		"Dialpad.display"	  /** Display dialpad preferences */
 #define CONFIG_SEARCHBAR	"Searchbar.display"	  /** Whether or nor display the search bar */