diff --git a/sflphone-common/src/sip/sdp.cpp b/sflphone-common/src/sip/sdp.cpp
index 771de13d676daead54396aad6b96133289d40b9c..b921c47e2d500df55689d9e6a67867151ba0a936 100644
--- a/sflphone-common/src/sip/sdp.cpp
+++ b/sflphone-common/src/sip/sdp.cpp
@@ -49,14 +49,20 @@ static const pj_str_t STR_CRYPTO = { (char*) "crypto", 6 };
 
 
 Sdp::Sdp (pj_pool_t *pool)
-    : _negociator (NULL)
-    , _local_media_cap()
-    , _session_media (0)
-    , localIpAddr ("")
+    : memPool (pool)
+	, negociator (NULL)
     , localSession (NULL)
-    , _negociated_offer (NULL)
-    , _pool (pool)
-    , localPublishedAudioPort (0)
+	, remoteSession(NULL)
+    , activeLocalSession (NULL)
+    , activeRemoteSession (NULL)
+    , localAudioMediaCap()
+    , sessionAudioMedia (0)
+    , localIpAddr ("")
+	, remoteIpAddr ("")
+    , localAudioPort (0)
+	, remoteAudioPort (0)
+	, zrtpHelloHash ("")
+	, srtpCrypto()
 {
 }
 
@@ -64,7 +70,93 @@ Sdp::~Sdp()
 {
 }
 
-void Sdp::set_media_descriptor_line (sdpMedia *media, pjmedia_sdp_media** p_med)
+void Sdp::setActiveLocalSdpSession (const pjmedia_sdp_session *sdp)
+{
+
+    int nb_media, nb_codecs;
+    int i,j, port;
+    pjmedia_sdp_media *current;
+    sdpMedia *media = NULL;
+    std::string type, dir;
+    CodecsMap codecs_list;
+    pjmedia_sdp_attr *attribute = NULL;
+    pjmedia_sdp_rtpmap *rtpmap;
+
+    _debug ("SDP: Set active local SDP session");
+
+    activeLocalSession = (pjmedia_sdp_session*) sdp;
+
+    codecs_list = Manager::instance().getCodecDescriptorMap().getCodecsMap();
+
+    // retrieve the media information
+    nb_media = activeLocalSession->media_count;
+
+    for (i=0; i<nb_media ; i++) {
+        // Retrieve the media
+        current = activeLocalSession->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++) {
+            attribute = pjmedia_sdp_media_find_attr (current, &STR_RTPMAP, NULL);
+            // pj_strtoul(attribute->pt)
+
+            if (!attribute)
+                return;
+
+            pjmedia_sdp_attr_to_rtpmap (memPool, attribute, &rtpmap);
+
+            CodecsMap::iterator iter = codecs_list.find ( (AudioCodecType) pj_strtoul (&rtpmap->pt));
+
+            if (iter==codecs_list.end())
+                return;
+
+            media->add_codec (iter->second);
+        }
+
+        sessionAudioMedia.push_back (media);
+    }
+}
+
+void Sdp::setActiveRemoteSdpSession (const pjmedia_sdp_session *sdp)
+{
+
+    std::string type, dir;
+    CodecsMap codecs_list;
+
+    _debug ("SDP: Set negotiated SDP");
+
+    activeRemoteSession = (pjmedia_sdp_session*) sdp;
+}
+
+AudioCodec* Sdp::getSessionMedia (void)
+{
+
+    int nb_media;
+    int nb_codec;
+    sfl::Codec *codec = NULL;
+    std::vector<sdpMedia*> media_list;
+
+    _debug ("SDP: Get session media");
+
+    media_list = getSessionMediaList ();
+    nb_media = media_list.size();
+
+    if (nb_media > 0) {
+        nb_codec = media_list[0]->get_media_codec_list().size();
+
+        if (nb_codec > 0) {
+            codec = media_list[0]->get_media_codec_list() [0];
+        }
+    }
+
+    return static_cast<AudioCodec *>(codec);
+}
+
+void Sdp::setMediaDescriptorLine (sdpMedia *media, pjmedia_sdp_media** p_med)
 {
 
     pjmedia_sdp_media* med;
@@ -74,21 +166,21 @@ void Sdp::set_media_descriptor_line (sdpMedia *media, pjmedia_sdp_media** p_med)
     int count, i;
     std::string tmp;
 
-    med = PJ_POOL_ZALLOC_T (_pool, pjmedia_sdp_media);
+    med = PJ_POOL_ZALLOC_T (memPool, pjmedia_sdp_media);
 
     // Get the right media format
-    pj_strdup (_pool, &med->desc.media,
+    pj_strdup (memPool, &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();
 
     // in case of sdes, media are tagged as "RTP/SAVP", RTP/AVP elsewhere
-    if (_srtp_crypto.empty()) {
+    if (srtpCrypto.empty()) {
 
-        pj_strdup (_pool, &med->desc.transport, &STR_RTP_AVP);
+        pj_strdup (memPool, &med->desc.transport, &STR_RTP_AVP);
     } else {
 
-        pj_strdup (_pool, &med->desc.transport, &STR_RTP_SAVP);
+        pj_strdup (memPool, &med->desc.transport, &STR_RTP_SAVP);
     }
 
     // Media format ( RTP payload )
@@ -99,9 +191,9 @@ void Sdp::set_media_descriptor_line (sdpMedia *media, pjmedia_sdp_media** p_med)
 
     for (i=0; i<count; i++) {
         codec = media->get_media_codec_list() [i];
-        tmp = this->convert_int_to_string (codec->getPayloadType ());
+        tmp = this->convertIntToString (codec->getPayloadType ());
         _debug ("%s", tmp.c_str());
-        pj_strdup2 (_pool, &med->desc.fmt[i], tmp.c_str());
+        pj_strdup2 (memPool, &med->desc.fmt[i], tmp.c_str());
 
         // Add a rtpmap field for each codec
         // We could add one only for dynamic payloads because the codecs with static RTP payloads
@@ -119,37 +211,71 @@ void Sdp::set_media_descriptor_line (sdpMedia *media, pjmedia_sdp_media** p_med)
 
         rtpmap.param.slen = 0;
 
-        pjmedia_sdp_rtpmap_to_attr (_pool, &rtpmap, &attr);
+        pjmedia_sdp_rtpmap_to_attr (memPool, &rtpmap, &attr);
 
         med->attr[med->attr_count++] = attr;
     }
 
     // Add the direction stream
-    attr = (pjmedia_sdp_attr*) pj_pool_zalloc (_pool, sizeof (pjmedia_sdp_attr));
+    attr = (pjmedia_sdp_attr*) pj_pool_zalloc (memPool, sizeof (pjmedia_sdp_attr));
 
-    pj_strdup2 (_pool, &attr->name, media->get_stream_direction_str().c_str());
+    pj_strdup2 (memPool, &attr->name, media->get_stream_direction_str().c_str());
 
     med->attr[ med->attr_count++] = attr;
 
-    if (!_zrtp_hello_hash.empty()) {
+    if (!zrtpHelloHash.empty()) {
         try {
-            sdp_add_zrtp_attribute (med,_zrtp_hello_hash);
+            addZrtpAttribute (med,zrtpHelloHash);
         } catch (...) {
             throw;
         }
-    } else {
-        _warn ("No hash specified");
     }
 
     *p_med = med;
 }
 
-int Sdp::createLocalSession (CodecOrder selectedCodecs)
+void Sdp::setLocalMediaCapabilities (CodecOrder selectedCodecs)
 {
 
-    pj_status_t status;
+    unsigned int i;
+    sdpMedia *audio;
+    CodecsMap codecs_list;
+    CodecsMap::iterator iter;
 
-    _info ("SDP: Create local offer");
+    // Clean it first
+    localAudioMediaCap.clear();
+
+    _debug ("SDP: Fetch local media capabilities. Local extern audio port: %i" , getLocalPublishedAudioPort());
+
+    /* Only one audio media used right now */
+    audio = new sdpMedia (MIME_TYPE_AUDIO);
+    audio->set_port (getLocalPublishedAudioPort());
+
+    /* We retrieve the codecs selected by the user */
+    codecs_list = Manager::instance().getCodecDescriptorMap().getCodecsMap();
+
+    if (selectedCodecs.size() == 0) {
+        throw SdpException ("No selected codec while building local SDP offer");
+    }
+
+    for (i=0; i<selectedCodecs.size(); i++) {
+        iter=codecs_list.find (selectedCodecs[i]);
+
+        if (iter!=codecs_list.end()) {
+            audio->add_codec (iter->second);
+        } else {
+            _warn ("SDP: Couldn't find audio codec");
+        }
+    }
+
+    localAudioMediaCap.push_back (audio);
+}
+
+int Sdp::createLocalSession (CodecOrder selectedCodecs)
+{
+    char buffer[1000];
+
+    _info ("SDP: Create local session");
 
     // Build local media capabilities
     setLocalMediaCapabilities (selectedCodecs);
@@ -157,29 +283,32 @@ int Sdp::createLocalSession (CodecOrder selectedCodecs)
     // Reference: RFC 4566 [5]
 
     /* Create and initialize basic SDP session */
-    this->localSession = PJ_POOL_ZALLOC_T (_pool, pjmedia_sdp_session);
-    this->localSession->conn = PJ_POOL_ZALLOC_T (_pool, pjmedia_sdp_conn);
+    localSession = PJ_POOL_ZALLOC_T (memPool, pjmedia_sdp_session);
+    localSession->conn = PJ_POOL_ZALLOC_T (memPool, pjmedia_sdp_conn);
 
     /* Initialize the fields of the struct */
-    sdp_add_protocol();
-    sdp_add_origin();
-    sdp_add_session_name();
-    sdp_add_connection_info();
-    sdp_add_timing();
-    sdp_add_media_description();
-
-    if (!_srtp_crypto.empty()) {
-        sdp_add_sdes_attribute (_srtp_crypto);
+    addProtocol();
+    addOrigin();
+    addSessionName();
+    addConnectionInfo();
+    addTiming();
+    addMediaDescription();
+
+    if (!srtpCrypto.empty()) {
+        addSdesAttribute (srtpCrypto);
     }
 
+    memset(buffer, 0, 1000);
+    pjmedia_sdp_print(getLocalSdpSession(), buffer, 1000);
+    _debug("SDP: Local SDP Session: %s\n\n", buffer);
+
     // Validate the sdp session
-    return pjmedia_sdp_validate (this->localSession);
+    return pjmedia_sdp_validate (localSession);
 
 }
 
-int Sdp::createInitialOffer (CodecOrder selectedCodecs)
+int Sdp::createOffer (CodecOrder selectedCodecs)
 {
-
     pj_status_t status;
     pjmedia_sdp_neg_state state;
 
@@ -187,33 +316,32 @@ int Sdp::createInitialOffer (CodecOrder selectedCodecs)
 
     // Build the SDP session descriptor
     status = createLocalSession (selectedCodecs);
-
     if (status != PJ_SUCCESS) {
         _error ("SDP: Error: Failed to create initial offer");
         return status;
     }
 
     // Create the SDP negociator instance with local offer
-    status = pjmedia_sdp_neg_create_w_local_offer (_pool, getLocalSdpSession(), &_negociator);
-
+    status = pjmedia_sdp_neg_create_w_local_offer (memPool, getLocalSdpSession(), &negociator);
     if (status != PJ_SUCCESS) {
         _error ("SDP: Error: Failed to create an initial SDP negociator");
         return status;
     }
 
-    state = pjmedia_sdp_neg_get_state (_negociator);
+    state = pjmedia_sdp_neg_get_state (negociator);
+
+    _debug("SDP: Negociator state %s\n", pjmedia_sdp_neg_state_str(state));
 
     PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1);
 
     return PJ_SUCCESS;
 }
 
-int Sdp::receivingInitialOffer (pjmedia_sdp_session* remote, CodecOrder selectedCodecs)
+int Sdp::recieveOffer (const pjmedia_sdp_session* remote, CodecOrder selectedCodecs)
 {
-    _debug ("SDP: Receiving initial offer");
+	char buffer[1000];
 
-    // 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 )
+    _debug ("SDP: Receiving initial offer");
 
     pj_status_t status;
 
@@ -221,63 +349,67 @@ int Sdp::receivingInitialOffer (pjmedia_sdp_session* remote, CodecOrder selected
         return !PJ_SUCCESS;
     }
 
-    // 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
-    status = createLocalSession (selectedCodecs);
-
-    if (status != PJ_SUCCESS) {
-        _error ("SDP: Error: Failed to create initial offer");
-        return status;
+    memset(buffer, 0, 1000);
+    pjmedia_sdp_print(remote, buffer, 1000);
+    _debug("SDP: Remote SDP Session: %s\n\n", buffer);
+
+    // If called for the first time
+    if(localSession == NULL) {
+        // Build the local offer to respond
+        status = createLocalSession (selectedCodecs);
+        if (status != PJ_SUCCESS) {
+            _error ("SDP: Error: Failed to create initial offer");
+            return status;
+        }
     }
 
-    // Retrieve some useful remote information
-    this->set_media_transport_info_from_remote_sdp (remote);
+    remoteSession = pjmedia_sdp_session_clone (memPool, remote);
 
-    status = pjmedia_sdp_neg_create_w_remote_offer (_pool, getLocalSdpSession(), remote, &_negociator);
+    status = pjmedia_sdp_neg_create_w_remote_offer (memPool, getLocalSdpSession(), getRemoteSdpSession(), &negociator);
 
     PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1);
 
     return PJ_SUCCESS;
 }
 
-int Sdp::receivingAnswerAfterInitialOffer(pjmedia_sdp_session* remote)
+int Sdp::receivingAnswerAfterInitialOffer(const pjmedia_sdp_session* remote)
 {
 	pj_status_t status;
 
-	if(pjmedia_sdp_neg_get_state(_negociator) != PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {
+	if(pjmedia_sdp_neg_get_state(negociator) != PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {
 		_warn("SDP: Session not in a valid state for receiving answer");
 	}
 
-	status = pjmedia_sdp_neg_set_remote_answer(_pool, _negociator, remote);
+	status = pjmedia_sdp_neg_set_remote_answer(memPool, negociator, remote);
 
 	if(status != PJ_SUCCESS) {
 		_warn("SDP: Error: Could not set SDP remote answer");
 	}
 
-	if(pjmedia_sdp_neg_get_state(_negociator) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
+	if(pjmedia_sdp_neg_get_state(negociator) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
 		_warn("SDP: Session not in a valid state after receiving answer");
 	}
 
+	_debug("SDP: Negotiator state %s\n", pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(negociator)));
+
 	return status;
 }
 
-int Sdp::generateAnswerFromInitialOffer(void)
+int Sdp::generateAnswerAfterInitialOffer(void)
 {
 	pj_status_t status;
 
-	if(pjmedia_sdp_neg_get_state(_negociator) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER) {
+	if(pjmedia_sdp_neg_get_state(negociator) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER) {
 		_warn("SDP: Session not in a valid state for generating answer");
 	}
 
-	status = pjmedia_sdp_neg_set_local_answer (_pool, _negociator, localSession);
+	status = pjmedia_sdp_neg_set_local_answer (memPool, negociator, localSession);
 
 	if(status != PJ_SUCCESS) {
 		_warn("SDP: Error: could not set SDP local answer");
 	}
 
-	if(pjmedia_sdp_neg_get_state(_negociator) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
+	if(pjmedia_sdp_neg_get_state(negociator) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
 		_warn("SDP: Session not in a valid state after generating answer");
 	}
 
@@ -288,95 +420,56 @@ int Sdp::generateAnswerFromInitialOffer(void)
 pj_status_t Sdp::startNegociation()
 {
     pj_status_t status;
+	const pjmedia_sdp_session *active_local;
+	const pjmedia_sdp_session *active_remote;
 
     _debug ("SDP: Start negotiation");
 
-    if(_negociator == NULL) {
+    if(negociator == NULL) {
     	_error("SDP: Error: Negociator is NULL in SDP session");
     }
 
-    if(pjmedia_sdp_neg_get_state(_negociator) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
+    if(pjmedia_sdp_neg_get_state(negociator) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
     	_warn("SDP: Warning: negociator not in wright state for negotiation");
     }
 
-    status = pjmedia_sdp_neg_negotiate (_pool, _negociator, 0);
+    status = pjmedia_sdp_neg_negotiate (memPool, negociator, 0);
+    if(status != PJ_SUCCESS) {
+    	return status;
+    }
+
+    _debug("SDP: Negotiator state %s\n", pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(negociator)));
+
+	status = pjmedia_sdp_neg_get_active_local(negociator, &active_local);
+	if(status != PJ_SUCCESS) {
+		_error("SDP: Could not retrieve local active session");
+	}
+
+	setActiveLocalSdpSession(active_local);
+
+	status = pjmedia_sdp_neg_get_active_remote(negociator, &active_remote);
+	if(status != PJ_SUCCESS) {
+		_error("SDP: Could not retrieve remote active session");
+	}
+
+	setActiveRemoteSdpSession(active_remote);
 
     return status;
 }
 
-//pj_status_t Sdp::check_sdp_answer (pjsip_inv_session *inv, pjsip_rx_data *rdata)
-//{
-//
-//    static const pj_str_t str_application = { (char*) "application", 11 };
-//    static const pj_str_t str_sdp = { (char*) "sdp", 3 };
-//    pj_status_t status;
-//    pjsip_msg * message = NULL;
-//    pjmedia_sdp_session * remote_sdp = NULL;
-//
-//    _debug ("Sdp: Check SDP answer");
-//
-//    if (pjmedia_sdp_neg_get_state (inv->neg) == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {
-//
-//        message = rdata->msg_info.msg;
-//
-//        if (message == NULL) {
-//            _error ("SDP: No message");
-//            return PJMEDIA_SDP_EINSDP;
-//        }
-//
-//        if (message->body == NULL) {
-//            _error ("SDP: Empty message body");
-//            return PJMEDIA_SDP_EINSDP;
-//        }
-//
-//        if (pj_stricmp (&message->body->content_type.type, &str_application) || pj_stricmp (&message->body->content_type.subtype, &str_sdp)) {
-//            _error ("SDP: Incoming Message does not contain SDP");
-//            return PJMEDIA_SDP_EINSDP;
-//        }
-//
-//        // Parse the SDP body.
-//        status = pjmedia_sdp_parse (rdata->tp_info.pool, (char*) message->body->data, message->body->len, &remote_sdp);
-//
-//        if (status == PJ_SUCCESS) {
-//            status = pjmedia_sdp_validate (remote_sdp);
-//        }
-//
-//        if (status != PJ_SUCCESS) {
-//            _warn ("SDP: cannot be validated");
-//            return PJMEDIA_SDP_EINSDP;
-//        }
-//
-//        // This is an answer
-//        _debug ("SDP: Got SDP answer %s", pjsip_rx_data_get_info (rdata));
-//
-//        status = pjmedia_sdp_neg_set_remote_answer (inv->pool, inv->neg, remote_sdp);
-//
-//        if (status != PJ_SUCCESS) {
-//            _error ("SDP: Error: while processing remote answer %s", pjsip_rx_data_get_info (rdata));
-//            return PJMEDIA_SDP_EINSDP;
-//        }
-//
-//        // Prefer our codecs to remote when possible
-//        pjmedia_sdp_neg_set_prefer_remote_codec_order (inv->neg, 0);
-//
-//        status = pjmedia_sdp_neg_negotiate (inv->pool, inv->neg, 0);
-//
-//        _debug ("Negotiation returned with status %d PJ_SUCCESS being %d", status, PJ_SUCCESS);
-//    } else {
-//        _debug ("No need to check sdp answer since we are UAS");
-//        return PJ_SUCCESS;
-//    }
-//
-//    return status;
-//}
-
-void Sdp::sdp_add_protocol (void)
+void Sdp::updateInternalState() {
+
+	// Populate internal field
+	setMediaTransportInfoFromRemoteSdp (activeRemoteSession);
+}
+
+void Sdp::addProtocol (void)
 {
 
     this->localSession->origin.version = 0;
 }
 
-void Sdp::sdp_add_origin (void)
+void Sdp::addOrigin (void)
 {
 
     pj_time_val tv;
@@ -393,14 +486,14 @@ void Sdp::sdp_add_origin (void)
     this->localSession->origin.addr = pj_str ( (char*) localIpAddr.c_str());
 }
 
-void Sdp::sdp_add_session_name (void)
+void Sdp::addSessionName (void)
 {
 
     this->localSession->name = STR_SDP_NAME;
 }
 
 
-void Sdp::sdp_add_connection_info (void)
+void Sdp::addConnectionInfo (void)
 {
 
     this->localSession->conn->net_type = localSession->origin.net_type;
@@ -409,7 +502,7 @@ void Sdp::sdp_add_connection_info (void)
 }
 
 
-void Sdp::sdp_add_timing (void)
+void Sdp::addTiming (void)
 {
 
     // RFC 3264: An offer/answer model session description protocol
@@ -419,33 +512,33 @@ void Sdp::sdp_add_timing (void)
     this->localSession->time.start = this->localSession->time.stop = 0;
 }
 
-void Sdp::sdp_add_attributes()
+void Sdp::addAttributes()
 {
 
     pjmedia_sdp_attr *a;
     this->localSession->attr_count = 1;
-    a =  PJ_POOL_ZALLOC_T (_pool, pjmedia_sdp_attr);
+    a =  PJ_POOL_ZALLOC_T (memPool, pjmedia_sdp_attr);
     a->name=STR_SENDRECV;
     localSession->attr[0] = a;
 }
 
 
-void Sdp::sdp_add_media_description()
+void Sdp::addMediaDescription()
 {
     pjmedia_sdp_media* med;
     int nb_media, i;
 
-    med = PJ_POOL_ZALLOC_T (_pool, pjmedia_sdp_media);
+    med = PJ_POOL_ZALLOC_T (memPool, pjmedia_sdp_media);
     nb_media = getLocalMediaCap().size();
     this->localSession->media_count = nb_media;
 
     for (i=0; i<nb_media; i++) {
-        set_media_descriptor_line (getLocalMediaCap() [i], &med);
+        setMediaDescriptorLine (getLocalMediaCap() [i], &med);
         this->localSession->media[i] = med;
     }
 }
 
-void Sdp::sdp_add_sdes_attribute (std::vector<std::string>& crypto) throw (SdpException)
+void Sdp::addSdesAttribute (std::vector<std::string>& crypto) throw (SdpException)
 {
 
     // temporary buffer used to store crypto attribute
@@ -456,9 +549,9 @@ void Sdp::sdp_add_sdes_attribute (std::vector<std::string>& crypto) throw (SdpEx
     while (iter != crypto.end()) {
 
         // the attribute to add to sdp
-        pjmedia_sdp_attr *attribute = (pjmedia_sdp_attr*) pj_pool_zalloc (_pool, sizeof (pjmedia_sdp_attr));
+        pjmedia_sdp_attr *attribute = (pjmedia_sdp_attr*) pj_pool_zalloc (memPool, sizeof (pjmedia_sdp_attr));
 
-        attribute->name = pj_strdup3 (_pool, "crypto");
+        attribute->name = pj_strdup3 (memPool, "crypto");
 
         // _debug("crypto from sdp: %s", crypto.c_str());
 
@@ -467,7 +560,7 @@ void Sdp::sdp_add_sdes_attribute (std::vector<std::string>& crypto) throw (SdpEx
                                     "%.*s", (int) (*iter).size(), (*iter).c_str());
 
         attribute->value.slen = len;
-        attribute->value.ptr = (char*) pj_pool_alloc (_pool, attribute->value.slen+1);
+        attribute->value.ptr = (char*) pj_pool_alloc (memPool, attribute->value.slen+1);
         pj_memcpy (attribute->value.ptr, tempbuf, attribute->value.slen+1);
 
         // get number of media for this SDP
@@ -488,15 +581,15 @@ void Sdp::sdp_add_sdes_attribute (std::vector<std::string>& crypto) throw (SdpEx
 }
 
 
-void Sdp::sdp_add_zrtp_attribute (pjmedia_sdp_media* media, std::string hash) throw (SdpException)
+void Sdp::addZrtpAttribute (pjmedia_sdp_media* media, std::string hash) throw (SdpException)
 {
     pjmedia_sdp_attr *attribute;
     char tempbuf[256];
     int len;
 
-    attribute = (pjmedia_sdp_attr*) pj_pool_zalloc (_pool, sizeof (pjmedia_sdp_attr));
+    attribute = (pjmedia_sdp_attr*) pj_pool_zalloc (memPool, sizeof (pjmedia_sdp_attr));
 
-    attribute->name = pj_strdup3 (_pool, "zrtp-hash");
+    attribute->name = pj_strdup3 (memPool, "zrtp-hash");
 
     /* Format: ":version value" */
     len = pj_ansi_snprintf (tempbuf, sizeof (tempbuf),
@@ -507,7 +600,7 @@ void Sdp::sdp_add_zrtp_attribute (pjmedia_sdp_media* media, std::string hash) th
                             hash.c_str());
 
     attribute->value.slen = len;
-    attribute->value.ptr = (char*) pj_pool_alloc (_pool, attribute->value.slen+1);
+    attribute->value.ptr = (char*) pj_pool_alloc (memPool, attribute->value.slen+1);
     pj_memcpy (attribute->value.ptr, tempbuf, attribute->value.slen+1);
 
     if (pjmedia_sdp_media_add_attr (media, attribute) != PJ_SUCCESS) {
@@ -515,15 +608,15 @@ void Sdp::sdp_add_zrtp_attribute (pjmedia_sdp_media* media, std::string hash) th
     }
 }
 
-std::string Sdp::media_to_string (void)
+std::string Sdp::mediaToString (void)
 {
     int size, i;
     std::ostringstream res;
 
-    size = _local_media_cap.size();
+    size = localAudioMediaCap.size();
 
     for (i = 0; i < size ; i++) {
-        res << _local_media_cap[i]->to_string();
+        res << localAudioMediaCap[i]->to_string();
     }
 
     res << std::endl;
@@ -535,117 +628,42 @@ void Sdp::clean_session_media()
 {
     _info ("SDP: Clean session media");
 
-    if (_session_media.size() > 0) {
+    if (sessionAudioMedia.size() > 0) {
 
-        std::vector<sdpMedia *>::iterator iter = _session_media.begin();
+        std::vector<sdpMedia *>::iterator iter = sessionAudioMedia.begin();
         sdpMedia *media;
 
-        while (iter != _session_media.end()) {
+        while (iter != sessionAudioMedia.end()) {
             _debug ("delete media");
             media = *iter;
             delete media;
             iter++;
         }
 
-        _session_media.clear();
+        sessionAudioMedia.clear();
     }
 }
 
 
-void Sdp::clean_local_media_capabilities()
+void Sdp::cleanLocalMediaCapabilities()
 {
     _info ("SDP: Clean local media capabilities");
 
-    if (_local_media_cap.size() > 0) {
+    if (localAudioMediaCap.size() > 0) {
 
-        std::vector<sdpMedia *>::iterator iter = _local_media_cap.begin();
+        std::vector<sdpMedia *>::iterator iter = localAudioMediaCap.begin();
         sdpMedia *media;
 
-        while (iter != _local_media_cap.end()) {
+        while (iter != localAudioMediaCap.end()) {
             media = *iter;
             delete media;
             iter++;
         }
 
-        _local_media_cap.clear();
-    }
-}
-
-void Sdp::set_negotiated_sdp (const pjmedia_sdp_session *sdp)
-{
-
-    int nb_media, nb_codecs;
-    int i,j, port;
-    pjmedia_sdp_media *current;
-    sdpMedia *media = NULL;
-    std::string type, dir;
-    CodecsMap codecs_list;
-    pjmedia_sdp_attr *attribute = NULL;
-    pjmedia_sdp_rtpmap *rtpmap;
-
-    _debug ("SDP: Set negotiated SDP");
-
-    _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++) {
-            attribute = pjmedia_sdp_media_find_attr (current, &STR_RTPMAP, NULL);
-            // pj_strtoul(attribute->pt)
-
-            if (!attribute)
-                return;
-
-            pjmedia_sdp_attr_to_rtpmap (_pool, attribute, &rtpmap);
-
-            CodecsMap::iterator iter = codecs_list.find ( (AudioCodecType) pj_strtoul (&rtpmap->pt));
-
-            if (iter==codecs_list.end())
-                return;
-
-            media->add_codec (iter->second);
-        }
-
-        _session_media.push_back (media);
+        localAudioMediaCap.clear();
     }
 }
 
-AudioCodec* Sdp::get_session_media (void)
-{
-
-    int nb_media;
-    int nb_codec;
-    sfl::Codec *codec = NULL;
-    std::vector<sdpMedia*> media_list;
-
-    _debug ("SDP: Get session media");
-
-    media_list = get_session_media_list ();
-    nb_media = media_list.size();
-
-    if (nb_media > 0) {
-        nb_codec = media_list[0]->get_media_codec_list().size();
-
-        if (nb_codec > 0) {
-            codec = media_list[0]->get_media_codec_list() [0];
-        }
-    }
-
-    return static_cast<AudioCodec *>(codec);
-}
-
 void Sdp::toString (void)
 {
 
@@ -683,44 +701,7 @@ void Sdp::toString (void)
     _debug ("LOCAL SDP: \n%s", sdp.str().c_str());
 }
 
-void Sdp::setLocalMediaCapabilities (CodecOrder selectedCodecs)
-{
-
-    unsigned int i;
-    sdpMedia *audio;
-    CodecsMap codecs_list;
-    CodecsMap::iterator iter;
-
-    // Clean it first
-    _local_media_cap.clear();
-
-    _debug ("SDP: Fetch local media capabilities. Local extern audio port: %i" , getLocalPublishedAudioPort());
-
-    /* Only one audio media used right now */
-    audio = new sdpMedia (MIME_TYPE_AUDIO);
-    audio->set_port (getLocalPublishedAudioPort());
-
-    /* We retrieve the codecs selected by the user */
-    codecs_list = Manager::instance().getCodecDescriptorMap().getCodecsMap();
-
-    if (selectedCodecs.size() == 0) {
-        throw SdpException ("No selected codec while building local SDP offer");
-    }
-
-    for (i=0; i<selectedCodecs.size(); i++) {
-        iter=codecs_list.find (selectedCodecs[i]);
-
-        if (iter!=codecs_list.end()) {
-            audio->add_codec (iter->second);
-        } else {
-            _warn ("SDP: Couldn't find audio codec");
-        }
-    }
-
-    _local_media_cap.push_back (audio);
-}
-
-void Sdp::attribute_port_to_all_media (int port)
+void Sdp::setPortToAllMedia (int port)
 {
 
     std::vector<sdpMedia*> medias;
@@ -736,14 +717,14 @@ void Sdp::attribute_port_to_all_media (int port)
     }
 }
 
-std::string Sdp::convert_int_to_string (int value)
+std::string Sdp::convertIntToString (int value)
 {
     std::ostringstream result;
     result << value;
     return result.str();
 }
 
-void Sdp::set_remote_ip_from_sdp (const pjmedia_sdp_session *r_sdp)
+void Sdp::setRemoteIpFromSdp (const pjmedia_sdp_session *r_sdp)
 {
 
     std::string remote_ip (r_sdp->conn->addr.ptr, r_sdp->conn->addr.slen);
@@ -751,7 +732,7 @@ void Sdp::set_remote_ip_from_sdp (const pjmedia_sdp_session *r_sdp)
     this->setRemoteIP (remote_ip);
 }
 
-void Sdp::set_remote_audio_port_from_sdp (pjmedia_sdp_media *r_media)
+void Sdp::setRemoteAudioPortFromSdp (pjmedia_sdp_media *r_media)
 {
 
     int remote_port;
@@ -761,7 +742,7 @@ void Sdp::set_remote_audio_port_from_sdp (pjmedia_sdp_media *r_media)
     this->setRemoteAudioPort (remote_port);
 }
 
-void Sdp::set_media_transport_info_from_remote_sdp (const pjmedia_sdp_session *remote_sdp)
+void Sdp::setMediaTransportInfoFromRemoteSdp (const pjmedia_sdp_session *remote_sdp)
 {
 
     _info ("SDP: Fetching media from sdp");
@@ -771,20 +752,20 @@ void Sdp::set_media_transport_info_from_remote_sdp (const pjmedia_sdp_session *r
 
     pjmedia_sdp_media *r_media;
 
-    this->get_remote_sdp_media_from_offer (remote_sdp, &r_media);
+    getRemoteSdpMediaFromOffer (remote_sdp, &r_media);
 
     if (r_media==NULL) {
         _warn ("SDP: Error: no remote sdp media found in the remote offer");
         return;
     }
 
-    this->set_remote_audio_port_from_sdp (r_media);
+    setRemoteAudioPortFromSdp (r_media);
 
-    this->set_remote_ip_from_sdp (remote_sdp);
+    setRemoteIpFromSdp (remote_sdp);
 
 }
 
-void Sdp::get_remote_sdp_media_from_offer (const pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media** r_media)
+void Sdp::getRemoteSdpMediaFromOffer (const pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media** r_media)
 {
     int count, i;
 
@@ -802,7 +783,7 @@ void Sdp::get_remote_sdp_media_from_offer (const pjmedia_sdp_session* remote_sdp
     }
 }
 
-void Sdp::get_remote_sdp_crypto_from_offer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer)
+void Sdp::getRemoteSdpCryptoFromOffer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer)
 {
 
     int i, j;
diff --git a/sflphone-common/src/sip/sdp.h b/sflphone-common/src/sip/sdp.h
index 613c8edb8b2b8e9e2f549eaf32a71e81fda9a51a..e44fcf5fa333607adb783d0e99da6c9e610b1ff8 100644
--- a/sflphone-common/src/sip/sdp.h
+++ b/sflphone-common/src/sip/sdp.h
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
- *
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -64,6 +64,7 @@ class SdpException : public std::exception
 };
 
 typedef std::vector<std::string> CryptoOffer;
+typedef std::vector<sdpMedia *> SdpMediaList;
 
 class Sdp
 {
@@ -85,31 +86,79 @@ class Sdp
          *
          * @return std::vector<sdpMedia*>   the vector containing the different media
          */
-        std::vector<sdpMedia*> getLocalMediaCap (void) {
-            return _local_media_cap;
+        std::vector<sdpMedia *> getLocalMediaCap (void) {
+            return localAudioMediaCap;
         }
 
-        /*
-        *  Read accessor. Get the sdp session information
-        *
-        *  @return pjmedia_sdp_session   The structure that describes a SDP session
-        */
-        pjmedia_sdp_session* getLocalSdpSession (void) {
-            return localSession;
-        }
 
         /**
          * Accessor for the internal memory pool
          */
         inline pj_pool_t *getMemoryPool (void) {
-            return _pool;
+            return memPool;
+        }
+
+        /**
+         *  Read accessor. Get the local passive sdp session information before negotiation
+         *
+         *  @return The structure that describes a SDP session
+         */
+        pjmedia_sdp_session *getLocalSdpSession (void) {
+            return localSession;
+        }
+
+        /**
+         * Read accessor. Get the remote passive sdp session information before negotiation
+         *
+         * @return The structure that describe the SDP session
+         */
+        pjmedia_sdp_session *getRemoteSdpSession(void) {
+        	return remoteSession;
+        }
+
+        /**
+         * Set the negociated sdp offer from the sip payload.
+         *
+         * @param sdp   the negociated offer
+         */
+        void setActiveLocalSdpSession (const pjmedia_sdp_session *sdp);
+
+        /**
+         * read accessor. Return the negociated local session
+         *
+         * @return pjmedia_sdp_session  The negociated offer
+         */
+        pjmedia_sdp_session* getActiveLocalSdpSession (void) {
+            return activeLocalSession;
+        }
+
+        /**
+         * Retrieve the negociated sdp offer from the sip payload.
+         *
+         * @param sdp   the negociated offer
+         */
+        void setActiveRemoteSdpSession (const pjmedia_sdp_session *sdp);
+
+        /**
+         * read accessor. Return the negociated offer
+         *
+         * @return pjmedia_sdp_session  The negociated offer
+         */
+        pjmedia_sdp_session* getActiveRemoteSdpSession (void) {
+            return activeRemoteSession;
         }
 
+
+        /**
+         * Return the codec of the first media after negociation
+         */
+        AudioCodec* getSessionMedia (void);
+
         /*
          * On building an invite outside a dialog, build the local offer and create the
          * SDP negociator instance with it.
          */
-        int createInitialOffer (CodecOrder selectedCodecs);
+        int createOffer (CodecOrder selectedCodecs);
 
         /*
         * On receiving an invite outside a dialog, build the local offer and create the
@@ -117,7 +166,7 @@ class Sdp
         *
         * @param remote    The remote offer
         */
-        int receivingInitialOffer (pjmedia_sdp_session* remote, CodecOrder selectedCodecs);
+        int recieveOffer (const pjmedia_sdp_session* remote, CodecOrder selectedCodecs);
 
         /*
          * On receiving a message, check if it contains SDP and negotiate. Should be used for
@@ -127,20 +176,25 @@ class Sdp
          * @param inv       The  the invitation
          * @param rdata     The remote data
          */
+        int receivingAnswerAfterInitialOffer(const pjmedia_sdp_session* remote);
 
-        int receivingAnswerAfterInitialOffer(pjmedia_sdp_session* remote);
-
-        int generateAnswerFromInitialOffer(void);
+        /**
+         * Generate answer after receiving Initial Offer
+         */
+        int generateAnswerAfterInitialOffer(void);
 
-        /*
-        * Start the sdp negociation.
-        *
-        * @return pj_status_t  0 on success
-        *                      1 otherwise
-        */
+        /**
+         * Start the sdp negociation.
+         *
+         * @return pj_status_t  0 on success
+         *                      1 otherwise
+         */
         pj_status_t startNegociation (void);
 
-        // pj_status_t check_sdp_answer (pjsip_inv_session *inv, pjsip_rx_data *rdata);
+        /**
+         * Update internal state after negotiation
+         */
+        void updateInternalState(void);
 
         /**
          * Remove all media in the session media vector.
@@ -150,35 +204,13 @@ class Sdp
         /**
          * Remove all media in local media capability vector
          */
-        void clean_local_media_capabilities (void);
+        void cleanLocalMediaCapabilities (void);
 
-        /*
+        /**
          * Return a string description of the media added to the session,
          * ie the local media capabilities
          */
-        std::string media_to_string (void);
-
-        /*
-         * 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;
-        }
-
-
-        /*
-        * Retrieve the negociated sdp offer from the sip payload.
-        *
-        * @param sdp   the negociated offer
-        */
-        void set_negotiated_sdp (const pjmedia_sdp_session *sdp);
+        std::string mediaToString (void);
 
         /*
          * Attribute the specified port to every medias provided
@@ -187,7 +219,7 @@ class Sdp
          *
          * @param port  The media port
          */
-        void attribute_port_to_all_media (int port);
+        void setPortToAllMedia (int port);
 
 
         /*
@@ -208,14 +240,14 @@ class Sdp
          * @param Set the published audio port
          */
         void  setLocalPublishedAudioPort (int port) {
-            localPublishedAudioPort = port;
+            localAudioPort = port;
         }
 
         /**
          * @return The published audio port
          */
         int  getLocalPublishedAudioPort (void) {
-            return localPublishedAudioPort;
+            return localAudioPort;
         }
 
         /**
@@ -250,31 +282,20 @@ class Sdp
             return remoteAudioPort;
         }
 
-        void set_media_transport_info_from_remote_sdp (const pjmedia_sdp_session *remote_sdp);
-
-        std::vector<sdpMedia*> get_session_media_list (void) {
-            return _session_media;
+        std::vector<sdpMedia*> getSessionMediaList (void) {
+            return sessionAudioMedia;
         }
 
-        void get_remote_sdp_crypto_from_offer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer);
+        void getRemoteSdpCryptoFromOffer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_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
-         */
-        void set_media_descriptor_line (sdpMedia* media, pjmedia_sdp_media** p_med);
-
         /* Set the zrtp hash that was previously calculated from the hello message in the zrtp layer.
          * This hash value is unique at the media level. Therefore, if video support is added, one would
          * have to set the correct zrtp-hash value in the corresponding media section.
          * @param hash The hello hash of a rtp session. (Only audio at the moment)
          */
         inline void set_zrtp_hash (const std::string& hash) {
-            _zrtp_hello_hash = hash;
+            zrtpHelloHash = hash;
             _debug ("Zrtp hash set with %s\n", hash.c_str());
         }
 
@@ -282,21 +303,21 @@ class Sdp
              * @param mk The Master Key of a srtp session.
              */
         inline void set_srtp_crypto (const std::vector<std::string> lc) {
-            _srtp_crypto = lc;
+            srtpCrypto = lc;
         }
 
         void toString (void);
 
-        /** negociator */
-        pjmedia_sdp_neg *_negociator;
 
     private:
-
         /**
          * The pool to allocate memory, ownership to SipCall
          * SDP should not release the pool itself
          */
-        pj_pool_t *_pool;
+        pj_pool_t *memPool;
+
+        /** negociator */
+        pjmedia_sdp_neg *negociator;
 
         /**
          * Local SDP
@@ -308,39 +329,73 @@ class Sdp
          */
         pjmedia_sdp_session *remoteSession;
 
-        /* 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;
+        /**
+         * The negociated SDP remote session
+         * 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 *activeLocalSession;
 
-        /** Codec Map */
-        std::vector<sdpMedia *> _local_media_cap;
+        /**
+         * The negociated SDP remote session
+         * 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 *activeRemoteSession;
 
-        /* The media that will be used by the session (after the SDP negociation) */
-        std::vector<sdpMedia *> _session_media;
+        /**
+         * Codec Map used for offer
+         */
+        SdpMediaList localAudioMediaCap;
 
-        /** IP address */
-        std::string localIpAddr;
+        /**
+         * The media that will be used by the session (after the SDP negociation)
+         */
+        SdpMediaList sessionAudioMedia;
 
-        /** Local audio port */
-        int localPublishedAudioPort;
+        /**
+         * IP address
+         */
+        std::string localIpAddr;
 
-        /** Remote's IP address */
+        /**
+         * Remote's IP address
+         */
         std::string  remoteIpAddr;
 
-        /** Remote audio port */
-        unsigned int remoteAudioPort;
+        /**
+         * Local audio port
+         */
+        int localAudioPort;
 
+        /**
+         * Remote audio port
+         */
+        unsigned int remoteAudioPort;
 
-        std::string _zrtp_hello_hash;
+        /**
+         * Zrtp hello hash
+         */
+        std::string zrtpHelloHash;
 
-        /** "a=crypto" sdes local attributes obtained from AudioSrtpSession */
-        std::vector<std::string> _srtp_crypto;
+        /**
+         * "a=crypto" sdes local attributes obtained from AudioSrtpSession
+         */
+        std::vector<std::string> srtpCrypto;
 
         Sdp (const Sdp&); //No Copy Constructor
 
         Sdp& operator= (const Sdp&); //No Assignment Operator
 
+        /*
+         * 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
+         */
+        void setMediaDescriptorLine (sdpMedia* media, pjmedia_sdp_media** p_med);
+
         /**
          * Build the local media capabilities for this session
          * @param List of codec in preference order
@@ -352,96 +407,89 @@ class Sdp
          */
         int createLocalSession (CodecOrder selectedCodecs);
 
+        /*
+         *  Mandatory field: Protocol version ("v=")
+         *  Add the protocol version in the SDP session description
+         */
+        void addProtocol (void);
+
         /*
          *  Mandatory field: Origin ("o=")
          *  Gives the originator of the session.
          *  Serves as a globally unique identifier for this version of this session description.
          */
-        void sdp_add_origin (void);
+        void addOrigin (void);
 
         /*
-         *  Mandatory field: Protocol version ("v=")
-         *  Add the protocol version in the SDP session description
+         *  Mandatory field: Session name ("s=")
+         *  Add a textual session name.
          */
-        void sdp_add_protocol (void);
+        void addSessionName (void);
 
         /*
          *  Optional field: Connection data ("c=")
          *  Contains connection data.
          */
-        void sdp_add_connection_info (void);
+        void addConnectionInfo (void);
 
         /*
-         *  Mandatory field: Session name ("s=")
-         *  Add a textual session name.
+         *  Mandatory field: Timing ("t=")
+         *  Specify the start and the stop time for a session.
          */
-        void sdp_add_session_name (void);
+        void addTiming (void);
+
 
         /*
          *  Optional field: Session information ("s=")
          *  Provides textual information about the session.
          */
-        void sdp_add_session_info (void) {}
+        void addSessionInfo (void) {}
 
         /*
          *  Optional field: Uri ("u=")
          *  Add a pointer to additional information about the session.
          */
-        void sdp_add_uri (void) {}
+        void addUri (void) {}
 
         /*
          *  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) {}
+        void addEmail (void) {}
 
         /*
          *  Optional field: Bandwidth ("b=")
          *  Denotes the proposed bandwidth to be used by the session or the media .
          */
-        void sdp_add_bandwidth (void) {}
+        void addBandwidth (void) {}
 
-        /*
-         *  Mandatory field: Timing ("t=")
-         *  Specify the start and the stop time for a session.
-         */
-        void sdp_add_timing (void);
 
         /*
          * Optional field: Time zones ("z=")
          */
-        void sdp_add_time_zone (void) {}
+        void addTimeZone (void) {}
 
         /*
          * Optional field: Encryption keys ("k=")
          */
-        void sdp_add_encryption_key (void) {}
+        void addEncryptionKey (void) {}
 
         /*
          * Optional field: Attributes ("a=")
          */
-        void sdp_add_attributes();
+        void addAttributes();
 
         /*
          * Mandatory field: Media descriptions ("m=")
          */
-        void sdp_add_media_description();
-
-        std::string convert_int_to_string (int value);
-
-        void set_remote_ip_from_sdp (const pjmedia_sdp_session *r_sdp);
-
-        void set_remote_audio_port_from_sdp (pjmedia_sdp_media *r_media);
-
-        void get_remote_sdp_media_from_offer (const pjmedia_sdp_session* r_sdp, pjmedia_sdp_media** r_media);
-
+        void addMediaDescription();
 
         /*
          * Adds a sdes attribute to the given media section.
          *
          * @param media The media to add the srtp attribute to
          */
-        void sdp_add_sdes_attribute (std::vector<std::string>& crypto) throw (SdpException);
+        void addSdesAttribute (std::vector<std::string>& crypto) throw (SdpException);
 
         /*
          * Adds a zrtp-hash  attribute to
@@ -452,7 +500,19 @@ class Sdp
          * @param media The media to add the zrtp-hash attribute to
          * @param hash  The hash to which the attribute should be set to
          */
-        void sdp_add_zrtp_attribute (pjmedia_sdp_media* media, std::string hash) throw (SdpException);
+        void addZrtpAttribute (pjmedia_sdp_media* media, std::string hash) throw (SdpException);
+
+        std::string convertIntToString (int value);
+
+        void setRemoteIpFromSdp (const pjmedia_sdp_session *r_sdp);
+
+        void setRemoteAudioPortFromSdp (pjmedia_sdp_media *r_media);
+
+        void setMediaTransportInfoFromRemoteSdp (const pjmedia_sdp_session *remote_sdp);
+
+        void getRemoteSdpMediaFromOffer (const pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media** r_media);
+
+
 
 };
 
diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp
index 3da10d680b5236ad7119ab207428d8d9a1098308..87a501d4b8f611429b7b23487c336a0ecaef18fe 100644
--- a/sflphone-common/src/sip/sipvoiplink.cpp
+++ b/sflphone-common/src/sip/sipvoiplink.cpp
@@ -185,24 +185,28 @@ void setVoicemailInfo (AccountID account, pjsip_msg_body *body);
 pj_bool_t stun_sock_on_status_cb (pj_stun_sock *stun_sock, pj_stun_sock_op op, pj_status_t status);
 pj_bool_t stun_sock_on_rx_data_cb (pj_stun_sock *stun_sock, void *pkt, unsigned pkt_len, const pj_sockaddr_t *src_addr, unsigned addr_len);
 
-
 /*
  * Session callback
- * Called when the invite session state has changed.
+ * Called after SDP offer/answer session has completed.
  *
  * @param	inv	A pointer on a pjsip_inv_session structure
- * @param	e	A pointer on a pjsip_event structure
+ * @param	status	A pj_status_t structure
  */
-void invite_session_state_changed_cb (pjsip_inv_session *inv, pjsip_event *e);
+void sdp_media_update_cb (pjsip_inv_session *inv, pj_status_t status UNUSED);
+
+
+void sdp_request_offer_cb (pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
+
+void sdp_create_offer_cb (pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
 
 /*
  * Session callback
- * Called after SDP offer/answer session has completed.
+ * Called when the invite session state has changed.
  *
  * @param	inv	A pointer on a pjsip_inv_session structure
- * @param	status	A pj_status_t structure
+ * @param	e	A pointer on a pjsip_event structure
  */
-void sdp_media_update_cb (pjsip_inv_session *inv, pj_status_t status UNUSED);
+void invite_session_state_changed_cb (pjsip_inv_session *inv, pjsip_event *e);
 
 /*
  * Called when the invite usage module has created a new dialog and invite
@@ -224,9 +228,6 @@ void outgoing_request_forked_cb (pjsip_inv_session *inv, pjsip_event *e);
  */
 void transaction_state_changed_cb (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
 
-void invite_request_offer_cb (pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
-
-void invite_create_offer_cb (pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
 
 /*
  * Registration callback
@@ -706,7 +707,7 @@ Call *SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
 
 	// Building the local SDP offer
 	call->getLocalSDP()->setLocalIP (addrSdp);
-	status = call->getLocalSDP()->createInitialOffer (account->getActiveCodecs ());
+	// status = call->getLocalSDP()->createOffer (account->getActiveCodecs ());
 
 	if (status != PJ_SUCCESS) {
 		delete call;
@@ -1042,7 +1043,7 @@ SIPVoIPLink::offhold (const CallID& id)
     }
 
     // Retreive previously selected codec
-    sfl::Codec *sessionMedia = call->getLocalSDP()->get_session_media();
+    sfl::Codec *sessionMedia = call->getLocalSDP()->getSessionMedia();
 
     if (!sessionMedia)
         return false;
@@ -1334,7 +1335,7 @@ SIPVoIPLink::getCurrentCodecName()
     call = getSIPCall (Manager::instance().getCurrentCallId());
 
     if (call)
-        ac = call->getLocalSDP()->get_session_media();
+        ac = call->getLocalSDP()->getSessionMedia();
 
     if (ac)
         name = ac->getMimeSubtype();
@@ -1759,7 +1760,7 @@ bool SIPVoIPLink::SIPNewIpToIpCall (const CallID& id, const std::string& to)
 
         // Building the local SDP offer
         call->getLocalSDP()->setLocalIP (addrSdp);
-        call->getLocalSDP()->createInitialOffer (account->getActiveCodecs ());
+        //call->getLocalSDP()->createOffer (account->getActiveCodecs ());
 
         // Init TLS transport if enabled
         if (account->isTlsEnabled()) {
@@ -1979,8 +1980,8 @@ bool SIPVoIPLink::pjsipInit()
     inv_cb.on_new_session = &outgoing_request_forked_cb;
     inv_cb.on_media_update = &sdp_media_update_cb;
     inv_cb.on_tsx_state_changed = &transaction_state_changed_cb;
-    inv_cb.on_rx_offer = &invite_request_offer_cb;
-    inv_cb.on_create_offer = &invite_create_offer_cb;
+    inv_cb.on_rx_offer = &sdp_request_offer_cb;
+    inv_cb.on_create_offer = &sdp_create_offer_cb;
 
     // Initialize session invite module
     status = pjsip_inv_usage_init (_endpt, &inv_cb);
@@ -3255,24 +3256,104 @@ void invite_session_state_changed_cb (pjsip_inv_session *inv, pjsip_event *e)
 
 }
 
+void sdp_request_offer_cb (pjsip_inv_session *inv, const pjmedia_sdp_session *offer)
+{
+    _info ("UserAgent: Received SDP offer");
+
+
+#ifdef CAN_REINVITE
+    _debug ("UserAgent: %s (%d): on_rx_offer REINVITE", __FILE__, __LINE__);
+
+    SIPCall *call;
+    pj_status_t status;
+    AccountID accId;
+    SIPVoIPLink *link;
+
+    call = (SIPCall*) inv->mod_data[getModId() ];
+
+    if (!call) {
+        return;
+    }
+
+    accId = Manager::instance().getAccountFromCall (call->getCallId());
+
+    link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
+
+    SIPAccount *account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (accId));
+
+    status = call->getLocalSDP()->recieveOffer (offer, account->getActiveCodecs ());
+    call->getLocalSDP()->startNegociation();
+
+    status = pjsip_inv_set_sdp_answer (call->getInvSession(), call->getLocalSDP()->getLocalSdpSession());
+
+    if (link) {
+        link->SIPHandleReinvite (call);
+    }
+#endif
+
+}
+
+void sdp_create_offer_cb (pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
+{
+    _info ("UserAgent: Create new SDP offer");
+
+    /* Retrieve the call information */
+    SIPCall * call = NULL;
+    call = reinterpret_cast<SIPCall*> (inv->mod_data[_mod_ua.id]);
+
+    CallID callid = call->getCallId();
+    AccountID accountid = Manager::instance().getAccountFromCall (callid);
+
+    SIPAccount *account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (accountid));
+
+    SIPVoIPLink *link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accountid));
+
+    // Set the local address
+    std::string localAddress = link->getInterfaceAddrFromName (account->getLocalInterface ());
+    // Set SDP parameters - Set to local
+    std::string addrSdp = localAddress;
+
+    _debug ("UserAgent: Local Address for IP2IP call: %s", localAddress.c_str());
+
+    // If local address bound to ANY, reslove it using PJSIP
+    if (localAddress == "0.0.0.0") {
+        link->loadSIPLocalIP (&localAddress);
+    }
+
+    // Local address to appear in SDP
+    if (addrSdp == "0.0.0.0") {
+        addrSdp = localAddress;
+    }
+
+    // Set local address for RTP media
+    setCallAudioLocal (call, localAddress);
+
+    // Building the local SDP offer
+    call->getLocalSDP()->setLocalIP (addrSdp);
+    call->getLocalSDP()->createOffer (account->getActiveCodecs());
+
+    *p_offer = call->getLocalSDP()->getLocalSdpSession();
+
+}
+
 // This callback is called after SDP offer/answer session has completed.
 void sdp_media_update_cb (pjsip_inv_session *inv, pj_status_t status)
 {
     _debug ("UserAgent: Call media update");
 
     const pjmedia_sdp_session *remote_sdp;
-
+    const pjmedia_sdp_session *local_sdp;
     SIPVoIPLink * link = NULL;
     SIPCall * call;
+    char buffer[1000];
 
     call = reinterpret_cast<SIPCall *> (inv->mod_data[getModId()]);
-    if (!call) {
+    if (call == NULL) {
         _debug ("UserAgent: Call declined by peer, SDP negociation stopped");
         return;
     }
 
     link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (AccountNULL));
-
     if (link == NULL) {
         _warn ("UserAgent: Error: Failed to get sip link");
         return;
@@ -3286,22 +3367,32 @@ void sdp_media_update_cb (pjsip_inv_session *inv, pj_status_t status)
     }
 
     if (!inv->neg) {
+    	_warn ("UserAgent: Error: no negotiator for this session");
         return;
     }
 
-    // Get sdp session from answer
+    // Retreive SDP session for this call
+    Sdp *sdpSession = call->getLocalSDP();
+
+    // Get active session sessions
     pjmedia_sdp_neg_get_active_remote (inv->neg, &remote_sdp);
+    pjmedia_sdp_neg_get_active_local (inv->neg, &local_sdp);
 
-    // Clean the resulting sdp offer to create a new one (in case of a reinvite)
-    call->getLocalSDP()->clean_session_media();
+    // Print SDP session
+	memset(buffer, 0, 1000);
+	pjmedia_sdp_print(remote_sdp, buffer, 1000);
+	_debug("SDP: Remote active SDP Session: %s\n", buffer);
 
-    // Set the fresh negotiated one, no matter if that was an offer or answer.
-    // The local sdp is updated in case of an answer, even if the remote sdp
-    // is kept internally.
-    call->getLocalSDP()->set_negotiated_sdp (remote_sdp);
+	memset(buffer, 0, 1000);
+	pjmedia_sdp_print(local_sdp, buffer, 1000);
+	_debug("SDP: Local active SDP Session: %s\n", buffer);
 
-    // Set remote ip / port
-    call->getLocalSDP()->set_media_transport_info_from_remote_sdp (remote_sdp);
+	// Set active SDP sessions
+    sdpSession->setActiveRemoteSdpSession(remote_sdp);
+    sdpSession->setActiveLocalSdpSession(local_sdp);
+
+    // Update internal field for
+    sdpSession->updateInternalState();
 
     try {
         call->getAudioRtp()->updateDestinationIpAddress();
@@ -3311,7 +3402,7 @@ void sdp_media_update_cb (pjsip_inv_session *inv, pj_status_t status)
 
     // Get the crypto attribute containing srtp's cryptographic context (keys, cipher)
     CryptoOffer crypto_offer;
-    call->getLocalSDP()->get_remote_sdp_crypto_from_offer (remote_sdp, crypto_offer);
+    call->getLocalSDP()->getRemoteSdpCryptoFromOffer (remote_sdp, crypto_offer);
 
     bool nego_success = false;
 
@@ -3364,14 +3455,10 @@ void sdp_media_update_cb (pjsip_inv_session *inv, pj_status_t status)
             call->getAudioRtp()->initAudioRtpSession (call);
     }
 
-    // Start audio rtp session.
-
-    Sdp  *sdpSession = call->getLocalSDP();
-
     if (!sdpSession)
         return;
 
-    AudioCodec *sessionMedia = sdpSession->get_session_media();
+    AudioCodec *sessionMedia = sdpSession->getSessionMedia();
 
     if (!sessionMedia)
         return;
@@ -3891,7 +3978,7 @@ transaction_request_cb (pjsip_rx_data *rdata)
     }
 
 
-    status = call->getLocalSDP()->receivingInitialOffer (r_sdp, account->getActiveCodecs ());
+    status = call->getLocalSDP()->recieveOffer (r_sdp, account->getActiveCodecs ());
 
     sfl::Codec* audiocodec = Manager::instance().getCodecDescriptorMap().instantiateCodec (PAYLOAD_CODEC_ULAW);
 
@@ -4428,83 +4515,6 @@ void transfer_server_cb (pjsip_evsub *sub, pjsip_event *event)
     }
 }
 
-void invite_request_offer_cb (pjsip_inv_session *inv, const pjmedia_sdp_session *offer UNUSED)
-{
-    _info ("UserAgent: Received SDP offer");
-
-
-#ifdef CAN_REINVITE
-    _debug ("UserAgent: %s (%d): on_rx_offer REINVITE", __FILE__, __LINE__);
-
-    SIPCall *call;
-    pj_status_t status;
-    AccountID accId;
-    SIPVoIPLink *link;
-
-    call = (SIPCall*) inv->mod_data[getModId() ];
-
-    if (!call)
-        return;
-
-    accId = Manager::instance().getAccountFromCall (call->getCallId());
-
-    link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
-
-    // call->getLocalSDP()->receiving_initial_offer ( (pjmedia_sdp_session*) offer, account->getActiveCodecs ());
-
-    status=pjsip_inv_set_sdp_answer (call->getInvSession(), call->getLocalSDP()->getLocalSdpSession());
-
-    if (link)
-        link->SIPHandleReinvite (call);
-
-#endif
-
-}
-
-void invite_create_offer_cb (pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
-{
-    _info ("UserAgent: Create new SDP offer");
-
-    /* Retrieve the call information */
-    SIPCall * call = NULL;
-    call = reinterpret_cast<SIPCall*> (inv->mod_data[_mod_ua.id]);
-
-    CallID callid = call->getCallId();
-    AccountID accountid = Manager::instance().getAccountFromCall (callid);
-
-    SIPAccount *account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (accountid));
-
-    SIPVoIPLink *link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accountid));
-
-    // Set the local address
-    std::string localAddress = link->getInterfaceAddrFromName (account->getLocalInterface ());
-    // Set SDP parameters - Set to local
-    std::string addrSdp = localAddress;
-
-    _debug ("UserAgent: Local Address for IP2IP call: %s", localAddress.c_str());
-
-    // If local address bound to ANY, reslove it using PJSIP
-    if (localAddress == "0.0.0.0") {
-        link->loadSIPLocalIP (&localAddress);
-    }
-
-    // Local address to appear in SDP
-    if (addrSdp == "0.0.0.0") {
-        addrSdp = localAddress;
-    }
-
-    // Set local address for RTP media
-    setCallAudioLocal (call, localAddress);
-
-    // Building the local SDP offer
-    call->getLocalSDP()->setLocalIP (addrSdp);
-    call->getLocalSDP()->createInitialOffer (account->getActiveCodecs());
-
-    *p_offer = call->getLocalSDP()->getLocalSdpSession();
-
-}
-
-
 void handleIncomingOptions (pjsip_rx_data *rdata)
 {
 
@@ -4595,7 +4605,7 @@ bool setCallAudioLocal (SIPCall* call, std::string localIP)
         call->setLocalAudioPort (callLocalAudioPort);
         call->setLocalExternAudioPort (callLocalExternAudioPort);
 
-        call->getLocalSDP()->attribute_port_to_all_media (callLocalExternAudioPort);
+        call->getLocalSDP()->setPortToAllMedia (callLocalExternAudioPort);
 
         return true;
     } else {
diff --git a/sflphone-common/test/sdptest.cpp b/sflphone-common/test/sdptest.cpp
index a078e0ebb7ef1a7a77bc0423c986ddc5bbcf6da3..9b5740a27a362cc8f4b32dedc6d9fc921f740809 100644
--- a/sflphone-common/test/sdptest.cpp
+++ b/sflphone-common/test/sdptest.cpp
@@ -28,9 +28,76 @@
  *  as that of the covered work.
  */
 
+#include <iostream>
+#include <string.h>
+
 #include "sdptest.h"
 
-#include <iostream>
+
+enum session_type
+{
+    REMOTE_OFFER,
+    LOCAL_OFFER,
+};
+
+static char *sdp_answer1 = "v=0\r\n"
+                           "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
+                           "s= \r\n"
+                           "c=IN IP4 host.example.com\r\n"
+                           "t=0 0\r\n"
+                           "m=audio 49920 RTP/AVP 0\r\n"
+                           "a=rtpmap:0 PCMU/8000\r\n"
+                           "m=video 0 RTP/AVP 31\r\n"
+                           "m=video 53002 RTP/AVP 32\r\n"
+                           "a=rtpmap:32 MPV/90000\r\n";
+
+static char *sdp_offer1 = "v=0\r\n"
+                          "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
+                          "s= \r\n"
+                          "c=IN IP4 host.example.com\r\n"
+                          "t=0 0\r\n"
+                          "m=audio 49920 RTP/AVP 0\r\n"
+                          "a=rtpmap:0 PCMU/8000\r\n"
+                          "m=video 0 RTP/AVP 31\r\n"
+                          "m=video 53002 RTP/AVP 32\r\n"
+                          "a=rtpmap:32 MPV/90000\r\n";
+
+static char *sdp_answer2 = "v=0\r\n"
+                           "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
+                           "s= \r\n"
+                           "c=IN IP4 host.example.com\r\n"
+                           "t=0 0\r\n"
+                           "m=audio 49920 RTP/AVP 3 97 9\r\n"
+                           "a=rtpmap:3 GSM/8000\r\n"
+		                   "a=rtpmap:97 iLBC/8000\r\n"
+		                   "a=rtpmap:9 G722/8000\r\n"
+                           "m=video 0 RTP/AVP 31\r\n"
+                           "m=video 53002 RTP/AVP 32\r\n"
+                           "a=rtpmap:32 MPV/90000\r\n";
+
+static char *sdp_offer2 = "v=0\r\n"
+                          "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
+                          "s= \r\n"
+                          "c=IN IP4 host.example.com\r\n"
+                          "t=0 0\r\n"
+                          "m=audio 49920 RTP/AVP 3 97 9\r\n"
+                          "a=rtpmap:3 GSM/8000\r\n"
+						  "a=rtpmap:97 iLBC/8000\r\n"
+                          "a=rtpmap:9 G722/8000\r\n"
+                          "m=video 0 RTP/AVP 31\r\n"
+                          "m=video 53002 RTP/AVP 32\r\n"
+                          "a=rtpmap:32 MPV/90000\r\n";
+
+static char *sdp_reinvite = "v=0\r\n"
+                            "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
+                            "s= \r\n"
+                            "c=IN IP4 host.exampleReinvite.com\r\n"
+                            "t=0 0\r\n"
+                            "m=audio 42445 RTP/AVP 0\r\n"
+                            "a=rtpmap:0 PCMU/8000\r\n"
+                            "m=video 0 RTP/AVP 31\r\n"
+                            "m=video 53002 RTP/AVP 32\r\n"
+                            "a=rtpmap:32 MPV/90000\r\n";
 
 
 void SDPTest::setUp()
@@ -47,19 +114,203 @@ void SDPTest::tearDown()
 	delete _session;
 	_session = NULL;
 
-        pj_pool_release(_testPool);
+    pj_pool_release(_testPool);
+}
+
+
+void SDPTest::testInitialOfferFirstCodec ()
+{
+	std::cout << "------------ SDPTest::testInitialOfferFirstCodec --------------" << std::endl;
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "");
+
+	CodecOrder codecSelection;
+    pjmedia_sdp_session *remoteAnswer;
+
+	codecSelection.push_back(PAYLOAD_CODEC_ULAW);
+	codecSelection.push_back(PAYLOAD_CODEC_ALAW);
+	codecSelection.push_back(PAYLOAD_CODEC_G722);
+
+	_session->setLocalIP("127.0.0.1");
+	_session->setLocalPublishedAudioPort(49567);
+
+    _session->createOffer(codecSelection);
+
+    // pjmedia_sdp_parse(_testPool, test[0].offer_answer[0].sdp2, strlen(test[0].offer_answer[0].sdp2), &remoteAnswer);
+    pjmedia_sdp_parse(_testPool, sdp_answer1, strlen(sdp_answer1), &remoteAnswer);
+
+    _session->receivingAnswerAfterInitialOffer(remoteAnswer);
+
+    _session->startNegociation();
+
+    _session->updateInternalState();
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 49567);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 49920);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "127.0.0.1");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "host.example.com");
+    CPPUNIT_ASSERT(_session->getSessionMedia()->getMimeSubtype() == "PCMU");
+
+}
+
+void SDPTest::testInitialAnswerFirstCodec ()
+{
+	std::cout << "------------ SDPTest::testInitialAnswerFirstCodec -------------" << std::endl;
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "");
+
+	CodecOrder codecSelection;
+    pjmedia_sdp_session *remoteOffer;
+
+	codecSelection.push_back(PAYLOAD_CODEC_ULAW);
+	codecSelection.push_back(PAYLOAD_CODEC_ALAW);
+	codecSelection.push_back(PAYLOAD_CODEC_G722);
+
+    pjmedia_sdp_parse(_testPool, sdp_offer1, strlen(sdp_offer1), &remoteOffer);
+
+    _session->setLocalIP("127.0.0.1");
+	_session->setLocalPublishedAudioPort(49567);
+
+    _session->recieveOffer(remoteOffer, codecSelection);
+
+    _session->startNegociation();
+
+    _session->updateInternalState();
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 49567);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 49920);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "127.0.0.1");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "host.example.com");
+    CPPUNIT_ASSERT(_session->getSessionMedia()->getMimeSubtype() == "PCMU");
+
+}
+
+void SDPTest::testInitialOfferLastCodec ()
+{
+	std::cout << "------------ SDPTest::testInitialOfferLastCodec --------------------" << std::endl;
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "");
+
+	CodecOrder codecSelection;
+    pjmedia_sdp_session *remoteAnswer;
+
+	codecSelection.push_back(PAYLOAD_CODEC_ULAW);
+	codecSelection.push_back(PAYLOAD_CODEC_ALAW);
+	codecSelection.push_back(PAYLOAD_CODEC_G722);
+
+	_session->setLocalIP("127.0.0.1");
+	_session->setLocalPublishedAudioPort(49567);
+
+    _session->createOffer(codecSelection);
+
+    // pjmedia_sdp_parse(_testPool, test[0].offer_answer[0].sdp2, strlen(test[0].offer_answer[0].sdp2), &remoteAnswer);
+    pjmedia_sdp_parse(_testPool, sdp_answer2, strlen(sdp_answer2), &remoteAnswer);
+
+    _session->receivingAnswerAfterInitialOffer(remoteAnswer);
+
+    _session->startNegociation();
+
+    _session->updateInternalState();
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 49567);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 49920);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "127.0.0.1");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "host.example.com");
+    CPPUNIT_ASSERT(_session->getSessionMedia()->getMimeSubtype() == "G722");
+
 }
 
+void SDPTest::testInitialAnswerLastCodec ()
+{
+	std::cout << "------------ SDPTest::testInitialAnswerLastCodec ------------" << std::endl;
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "");
+
+	CodecOrder codecSelection;
+    pjmedia_sdp_session *remoteOffer;
 
-void SDPTest::testInitialOffer ()
+	codecSelection.push_back(PAYLOAD_CODEC_ULAW);
+	codecSelection.push_back(PAYLOAD_CODEC_ALAW);
+	codecSelection.push_back(PAYLOAD_CODEC_G722);
+
+    pjmedia_sdp_parse(_testPool, sdp_offer2, strlen(sdp_offer2), &remoteOffer);
+
+    _session->setLocalIP("127.0.0.1");
+	_session->setLocalPublishedAudioPort(49567);
+
+    _session->recieveOffer(remoteOffer, codecSelection);
+
+    _session->startNegociation();
+
+    _session->updateInternalState();
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 49567);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 49920);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "127.0.0.1");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "host.example.com");
+    CPPUNIT_ASSERT(_session->getSessionMedia()->getMimeSubtype() == "G722");
+
+}
+
+
+void SDPTest::testReinvite ()
 {
-	std::cout << "-------------------- SDPTest::testInitialOffer --------------------" << std::endl;
+	std::cout << "------------ SDPTest::testReinvite --------------------" << std::endl;
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 0);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "");
 
 	CodecOrder codecSelection;
+    pjmedia_sdp_session *remoteAnswer;
+    pjmedia_sdp_session *reinviteOffer;
 
 	codecSelection.push_back(PAYLOAD_CODEC_ULAW);
 	codecSelection.push_back(PAYLOAD_CODEC_ALAW);
 	codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-        _session->createInitialOffer(codecSelection);
+	_session->setLocalIP("127.0.0.1");
+	_session->setLocalPublishedAudioPort(49567);
+
+    _session->createOffer(codecSelection);
+
+    // pjmedia_sdp_parse(_testPool, test[0].offer_answer[0].sdp2, strlen(test[0].offer_answer[0].sdp2), &remoteAnswer);
+    pjmedia_sdp_parse(_testPool, sdp_answer1, strlen(sdp_answer1), &remoteAnswer);
+
+    _session->receivingAnswerAfterInitialOffer(remoteAnswer);
+
+    _session->startNegociation();
+
+    _session->updateInternalState();
+
+    CPPUNIT_ASSERT(_session->getLocalPublishedAudioPort() == 49567);
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 49920);
+    CPPUNIT_ASSERT(_session->getLocalIP() == "127.0.0.1");
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "host.example.com");
+    CPPUNIT_ASSERT(_session->getSessionMedia()->getMimeSubtype() == "PCMU");
+
+    pjmedia_sdp_parse(_testPool, sdp_reinvite, strlen(sdp_reinvite), &reinviteOffer);
+
+    _session->recieveOffer(reinviteOffer, codecSelection);
+
+    _session->startNegociation();
+
+    _session->updateInternalState();
+
+    CPPUNIT_ASSERT(_session->getRemoteAudioPort() == 42445);
+    CPPUNIT_ASSERT(_session->getRemoteIP() == "host.exampleReinvite.com");
+
 }
diff --git a/sflphone-common/test/sdptest.h b/sflphone-common/test/sdptest.h
index 0b4888dc7b497d45f62f616d7272cdaad067f465..e810082403cf7f25bc2e4361be04cec6b0424b55 100644
--- a/sflphone-common/test/sdptest.h
+++ b/sflphone-common/test/sdptest.h
@@ -84,27 +84,39 @@ class SDPTest : public CppUnit::TestCase {
      * Use cppunit library macros to add unit test the factory
      */
     CPPUNIT_TEST_SUITE( SDPTest );
-    CPPUNIT_TEST ( testInitialOffer );
+    CPPUNIT_TEST ( testInitialOfferLastCodec );
+    CPPUNIT_TEST ( testInitialAnswerLastCodec );
+    CPPUNIT_TEST ( testInitialOfferLastCodec );
+    CPPUNIT_TEST ( testInitialAnswerLastCodec );
+    CPPUNIT_TEST ( testReinvite );
     CPPUNIT_TEST_SUITE_END();
 
-    public:
-        SDPTest() : CppUnit::TestCase("SDP module Tests") {}
+public:
+    SDPTest() : CppUnit::TestCase("SDP module Tests") {}
         
-        /*
-         * Code factoring - Common resources can be initialized here.
-         * This method is called by unitcpp before each test
-         */
-        void setUp();
+    /**
+     * Code factoring - Common resources can be initialized here.
+     * This method is called by unitcpp before each test
+     */
+    void setUp();
 
-        /*
-         * Code factoring - Common resources can be released here.
-         * This method is called by unitcpp after each test
-         */
-        inline void tearDown ();
+    /**
+     * Code factoring - Common resources can be released here.
+     * This method is called by unitcpp after each test
+     */
+    inline void tearDown ();
 
-	void testInitialOffer();
+	void testInitialOfferFirstCodec();
 
-    private:
+	void testInitialAnswerFirstCodec();
+
+	void testInitialOfferLastCodec();
+
+	void testInitialAnswerLastCodec();
+
+	void testReinvite ();
+
+private:
 
 	Sdp *_session;