diff --git a/sflphone-common/src/sdp.cpp b/sflphone-common/src/sdp.cpp
index 9256b238b8ca8db8dd1cf6341e296940d5b1c4da..2bd7420dbf658332d875cce60a04872fc4836b83 100644
--- a/sflphone-common/src/sdp.cpp
+++ b/sflphone-common/src/sdp.cpp
@@ -180,7 +180,6 @@ int Sdp::receiving_initial_offer (pjmedia_sdp_session* remote)
     // 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;
 
     _debug ("Receiving initial offer\n");
 
@@ -200,13 +199,61 @@ int Sdp::receiving_initial_offer (pjmedia_sdp_session* remote)
     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 PJ_SUCCESS;
 }
 
+pj_status_t Sdp::check_incoming_sdp(pjsip_inv_session *inv, pjsip_rx_data *rdata) 
+{
+    static const pj_str_t str_application = { "application", 11 };
+    static const pj_str_t str_sdp = { "sdp", 3 };
+    pj_status_t status;
+    pjsip_msg * message;
+    pjmedia_sdp_session * remote_sdp;
+    
+    message = rdata->msg_info.msg;
+    if (message->body == NULL) {
+        _debug("Empty message body\n");
+        return -1;
+    }
+    
+    if (pj_stricmp(&message->body->content_type.type, &str_application) || pj_stricmp(&message->body->content_type.subtype, &str_sdp)) {
+        _debug("Incoming Message does not contain SDP\n");
+        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) {
+        _debug("SDP cannot be validated\n");
+        return PJMEDIA_SDP_EINSDP;
+    }
+    
+    if (pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) {
+        // This is an answer
+        _debug("Got SDP answer %s\n", pjsip_rx_data_get_info(rdata));
+        status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg, remote_sdp);
+        
+        if (status != PJ_SUCCESS) {
+            _debug("An error occured while processing remote answer %s\n", 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\n", status, PJ_SUCCESS); 
+    }
+    
+    return status;
+}
+
 void Sdp::sdp_add_protocol (void)
 {
     this->_local_offer->origin.version = 0;
@@ -298,7 +345,7 @@ void Sdp::clean_session_media()
     _session_media.clear();
 }
 
-void Sdp::set_negociated_offer (const pjmedia_sdp_session *sdp)
+void Sdp::set_negotiated_sdp (const pjmedia_sdp_session *sdp)
 {
 
     int nb_media, nb_codecs;
diff --git a/sflphone-common/src/sdp.h b/sflphone-common/src/sdp.h
index ec3178955b57c5370872d43ada2c92302f9f18af..b32f9886f681749b46dcd36100e3866df96248bd 100644
--- a/sflphone-common/src/sdp.h
+++ b/sflphone-common/src/sdp.h
@@ -25,6 +25,8 @@
 #include <pjmedia/sdp_neg.h>
 #include <pjsip/sip_transport.h>
 #include <pjlib.h>
+#include <pjsip_ua.h>
+#include <pjmedia/errno.h>
 #include <pj/pool.h>
 #include <pj/assert.h>
 
@@ -97,6 +99,17 @@ class Sdp {
          */
         int receiving_initial_offer( pjmedia_sdp_session* remote );
         
+        /*
+         * On receiving a message, check if it contains SDP and negotiate. Should be used for
+         * SDP answer and offer but currently is only used for answer.
+         * SDP negociator instance with the remote offer.
+         *
+         * @param inv       The  the invitation
+         * @param rdata     The remote data
+         */
+        
+        pj_status_t check_incoming_sdp(pjsip_inv_session *inv, pjsip_rx_data *rdata);
+        
         /*
          * Remove all media in the session media vector.
          */
@@ -138,7 +151,7 @@ class Sdp {
          *
          * @param sdp   the negociated offer
          */
-        void set_negociated_offer( const pjmedia_sdp_session *sdp );
+        void set_negotiated_sdp ( const pjmedia_sdp_session *sdp );
 
         /*
          * Attribute the specified port to every medias provided
diff --git a/sflphone-common/src/sipvoiplink.cpp b/sflphone-common/src/sipvoiplink.cpp
index af41b6d268c760870fcca500204e488df9331432..13f7fa47ebfed7e8dc598ebad4532cb0ffcacb56 100644
--- a/sflphone-common/src/sipvoiplink.cpp
+++ b/sflphone-common/src/sipvoiplink.cpp
@@ -503,7 +503,6 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
 
     SIPCall* call = new SIPCall (id, Call::Outgoing, _pool);
 
-
     if (call) {
         account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (Manager::instance().getAccountFromCall (id)));
 
@@ -520,7 +519,6 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
 
         setCallAudioLocal (call, getLocalIPAddress(), useStun(), getStunServer());
 
-
         try {
             _debug ("CREATE NEW RTP SESSION FROM NEWOUTGOINGCALL\n");
             _audiortp->createNewSession (call);
@@ -528,9 +526,6 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
             _debug ("Failed to create rtp thread from newOutGoingCall\n");
         }
 
-
-
-
         call->initRecFileName();
 
         _debug ("Try to make a call to: %s with call ID: %s\n", toUrl.data(), id.data());
@@ -560,8 +555,6 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
 bool
 SIPVoIPLink::answer (const CallID& id)
 {
-
-    int i;
     SIPCall *call;
     pj_status_t status;
     pjsip_tx_data *tdata;
@@ -1415,7 +1408,6 @@ bool get_dns_server_addresses (std::vector<std::string> *servers)
         nameservers.push_back (inet_ntoa (address));
     }
 
-    //nameservers.push_back ("192.168.50.3");
     *servers = nameservers;
 
     return true;
@@ -1427,8 +1419,6 @@ pj_status_t SIPVoIPLink::enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_
     pj_status_t status;
     pj_dns_resolver *resv;
     std::vector <std::string> dns_servers;
-    pj_uint16_t port = 5353;
-    pjsip_resolver_t *res;
     int scount, i;
 
     // Create the DNS resolver instance
@@ -1706,13 +1696,10 @@ int SIPVoIPLink::createUDPServer (void)
     pj_sockaddr_in bound_addr;
     pjsip_host_port a_name;
     char tmpIP[32];
-    pj_sock_t sock;
-
 
     // 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;
@@ -1875,22 +1862,17 @@ void SIPVoIPLink::handle_reinvite (SIPCall *call)
     }
 }
 
-
-/*******************************/
-/*   CALLBACKS IMPLEMENTATION  */
-/*******************************/
-
+// This callback is called when the invite session state has changed
 void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
 {
-
     _debug ("--------------------- call_on_state_changed --------------------- %i\n", inv->state);
 
     SIPCall *call;
     AccountID accId;
     SIPVoIPLink *link;
     pjsip_rx_data *rdata;
-
-
+    pj_status_t status;
+    
     /* Retrieve the call information */
     call = reinterpret_cast<SIPCall*> (inv->mod_data[_mod_ua.id]);
 
@@ -1900,7 +1882,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
     //Retrieve the body message
     rdata = e->body.tsx_state.src.rdata;
 
-
+    
     /* If this is an outgoing INVITE that was created because of
      * REFER/transfer, send NOTIFY to transferer.
      */
@@ -1961,84 +1943,104 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
                 }
             }
         }
-    } else {
+        
+        return;
+    }
+    
+    // The call is ringing - We need to handle this case only on outgoing call
+    if (inv->state == PJSIP_INV_STATE_EARLY && e->body.tsx_state.tsx->role == PJSIP_ROLE_UAC) {
+        call->setConnectionState (Call::Ringing);
+        Manager::instance().peerRingingCall (call->getCallId());
+    } 
+    // After 2xx is sent/received.
+    else if (inv->state == PJSIP_INV_STATE_CONNECTING) {
+        status = call->getLocalSDP()->check_incoming_sdp (inv, rdata);    
+        if (status != PJ_SUCCESS) {
+            _debug("Failed to check_incoming_sdp in call_on_state_changed\n");
+            return;
+        }
+    }
+    // After we sent or received a ACK - The connection is established
+    else if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
 
-        // The call is ringing - We need to handle this case only on outgoing call
-        if (inv->state == PJSIP_INV_STATE_EARLY && e->body.tsx_state.tsx->role == PJSIP_ROLE_UAC) {
-            call->setConnectionState (Call::Ringing);
-            Manager::instance().peerRingingCall (call->getCallId());
+        /* If the call is a direct IP-to-IP call */
+        if (call->getCallConfiguration () == Call::IPtoIP) {
+            link = SIPVoIPLink::instance ("");
+        } else {
+            accId = Manager::instance().getAccountFromCall (call->getCallId());
+            link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
         }
 
-        // We receive a ACK - The connection is established
-        else if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
+        if (link)
+            link->SIPCallAnswered (call, rdata);
+    }
+    else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+        _debug ("------------------- Call disconnected ---------------------\n");
+        _debug ("State: %i, Disconnection cause: %i\n", inv->state, inv->cause);
 
-            /* If the call is a direct IP-to-IP call */
-            if (call->getCallConfiguration () == Call::IPtoIP) {
-                link = SIPVoIPLink::instance ("");
-            } else {
+        switch (inv->cause) {
+                /* The call terminates normally - BYE / CANCEL */
+            case PJSIP_SC_OK:
+            case PJSIP_SC_DECLINE:
+            case PJSIP_SC_REQUEST_TERMINATED:
                 accId = Manager::instance().getAccountFromCall (call->getCallId());
                 link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
-            }
-
-            if (link)
-                link->SIPCallAnswered (call, rdata);
-        }
-
-        else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
-            int count = 0;
-            _debug ("------------------- Call disconnected ---------------------\n");
-            _debug ("State: %i, Disconnection cause: %i\n", inv->state, inv->cause);
-
-            switch (inv->cause) {
-                    /* The call terminates normally - BYE / CANCEL */
-
-                case PJSIP_SC_OK:
-
-                case PJSIP_SC_DECLINE:
-
-                case PJSIP_SC_REQUEST_TERMINATED:
 
-                    accId = Manager::instance().getAccountFromCall (call->getCallId());
-                    link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
-
-                    if (link) {
-                        link->SIPCallClosed (call);
-                    }
-
-                    break;
+                if (link) {
+                    link->SIPCallClosed (call);
+                }
 
-                    /* The call connection failed */
+                break;
+             /* The call connection failed */
+            case PJSIP_SC_NOT_FOUND:            /* peer not found */
+            case PJSIP_SC_REQUEST_TIMEOUT:      /* request timeout */
+            case PJSIP_SC_NOT_ACCEPTABLE_HERE:  /* no compatible codecs */
+            case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE:
+            case PJSIP_SC_UNSUPPORTED_MEDIA_TYPE:
+            case PJSIP_SC_UNAUTHORIZED:
+            case PJSIP_SC_REQUEST_PENDING:
+                accId = Manager::instance().getAccountFromCall (call->getCallId());
+                link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
 
-                case PJSIP_SC_NOT_FOUND:            /* peer not found */
+                if (link) {
+                    link->SIPCallServerFailure (call);
+                }
 
-                case PJSIP_SC_REQUEST_TIMEOUT:      /* request timeout */
+                break;
+            default:
+                _debug ("sipvoiplink.cpp - line %d : Unhandled call state. This is probably a bug.\n", __LINE__);
+                break;
+        }
+    }
+  
+}
 
-                case PJSIP_SC_NOT_ACCEPTABLE_HERE:  /* no compatible codecs */
+int terminate_call_bad_sdp_answer(SIPCall * call, SIPVoIPLink * link)
+{
+    pj_status_t status;
+    pjsip_tx_data *tdata = NULL;
+    
+    status = pjsip_inv_end_session(call->getInvSession(), 488, NULL, &tdata);
 
-                case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE:
+    if (status != PJ_SUCCESS)
+        return false;
 
-                case PJSIP_SC_UNSUPPORTED_MEDIA_TYPE:
+    if (tdata == NULL)
+        return true;
 
-                case PJSIP_SC_UNAUTHORIZED:
+    status = pjsip_inv_send_msg (call->getInvSession(), tdata);
 
-                case PJSIP_SC_REQUEST_PENDING:
-                    accId = Manager::instance().getAccountFromCall (call->getCallId());
-                    link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
+    if (status != PJ_SUCCESS)
+        return false;
 
-                    if (link) {
-                        link->SIPCallServerFailure (call);
-                    }
+    call->getInvSession()->mod_data[getModId() ] = NULL;
 
-                    break;
+    link->terminateOneCall (call->getCallId());
 
-                default:
-                    _debug ("sipvoiplink.cpp - line %d : Unhandled call state. This is probably a bug.\n", __LINE__);
-                    break;
-            }
-        }
-    }
+    link->removeCall (call->getCallId());
 }
 
+// This callback is called after SDP offer/answer session has completed.
 void call_on_media_update (pjsip_inv_session *inv, pj_status_t status)
 {
     _debug ("--------------------- call_on_media_update --------------------- \n");
@@ -2048,38 +2050,42 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status)
     
     SIPVoIPLink * link = NULL;
     SIPCall * call;
-
-    if (status != PJ_SUCCESS) {
-        _debug ("Error while negociating the offer\n");
-        return;
-    }
-
-    // Get the new sdp, result of the negociation
-    pjmedia_sdp_neg_get_active_local (inv->neg, &local_sdp);
-    pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
-     
+    
     call = reinterpret_cast<SIPCall *> (inv->mod_data[getModId() ]);
 
     if (!call) {
         _debug ("Call declined by peer, SDP negociation stopped\n");
         return;
     }
-        
-    // Clean the resulting sdp offer to create a new one (in case of a reinvite)
-    call->getLocalSDP()->clean_session_media();
-    
-    // Set the fresh negociated one
-    call->getLocalSDP()->set_negociated_offer (local_sdp);
 
-    // Set remote ip / port  
-    call->getLocalSDP()->set_media_transport_info_from_remote_sdp (remote_sdp); 
-    
     link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink(AccountNULL));
     if(link == NULL) {
         _debug ("Failed to get sip link\n");
         return;
     }
     
+    if (status != PJ_SUCCESS) {
+        _debug ("Error while negotiating the offer\n");
+        //terminate_call_bad_sdp_answer(call, link);
+        link->hangup(call->getCallId());
+        return;
+    }
+
+    // Get the new sdp, result of the negotiation
+    pjmedia_sdp_neg_get_active_local  (inv->neg, &local_sdp);
+    pjmedia_sdp_neg_get_active_remote (inv->neg, &remote_sdp);
+        
+    // Clean the resulting sdp offer to create a new one (in case of a reinvite)
+    call->getLocalSDP()->clean_session_media();
+    
+    // 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 (local_sdp);
+
+    // Set remote ip / port  
+    call->getLocalSDP()->set_media_transport_info_from_remote_sdp (remote_sdp); 
+        
     try {    
         call->setAudioStart (true);
         link->getAudioRtp()->start();
@@ -2107,11 +2113,8 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_
 
 void regc_cb (struct pjsip_regc_cbparam *param)
 {
-
-    //AccountID *id = static_cast<AccountID *> (param->token);
     SIPAccount *account;
 
-    //_debug("UserAgent: Account ID is %s, Register result: %d, Status: %d\n", id->data(), param->status, param->code);
     account = static_cast<SIPAccount *> (param->token);
 
     if (!account)
@@ -2167,11 +2170,10 @@ void regc_cb (struct pjsip_regc_cbparam *param)
 
 }
 
+// Optional function to be called to process incoming request message.
 pj_bool_t
 mod_on_rx_request (pjsip_rx_data *rdata)
 {
-
-
     pj_status_t status;
     pj_str_t reason;
     unsigned options = 0;
@@ -2325,7 +2327,6 @@ mod_on_rx_request (pjsip_rx_data *rdata)
 
     get_remote_sdp_from_offer (rdata, &r_sdp);
 
-// 	_debug("r_sdp = %s\n", r_sdp);
     status = call->getLocalSDP()->receiving_initial_offer (r_sdp);
 
     if (status!=PJ_SUCCESS) {
@@ -2334,7 +2335,6 @@ mod_on_rx_request (pjsip_rx_data *rdata)
         return false;
     }
 
-
     call->setConnectionState (Call::Progressing);
 
     call->setPeerNumber (peerNumber);
@@ -2364,7 +2364,6 @@ mod_on_rx_request (pjsip_rx_data *rdata)
         return true;
     }
 
-
     // Specify media capability during invite session creation
     status = pjsip_inv_create_uas (dialog, rdata, call->getLocalSDP()->get_local_sdp_session(), 0, &inv);