diff --git a/daemon/src/call.h b/daemon/src/call.h
index 281f8967241f487d96d3bc2790c735a78592052d..2a4b8da43b2a4241127832b1bb66d8fad5479912 100644
--- a/daemon/src/call.h
+++ b/daemon/src/call.h
@@ -173,8 +173,6 @@ class Call : public Recordable {
             isIPToIP_ = IPToIP;
         }
 
-        virtual void answer() = 0;
-
         /**
          * Set my IP [not protected]
          * @param ip  The local IP address
diff --git a/daemon/src/iax/iaxcall.h b/daemon/src/iax/iaxcall.h
index 1cf5233cea23d6af5b13e37b4d81333e49e1d771..d9dfde77009e8ebaf08a259e03cb9ec0a4d38465 100644
--- a/daemon/src/iax/iaxcall.h
+++ b/daemon/src/iax/iaxcall.h
@@ -71,10 +71,11 @@ class IAXCall : public Call {
 
         int getAudioCodec() const;
 
+        void answer();
+
         int format;
         iax_session* session;
     private:
-        virtual void answer();
         NON_COPYABLE(IAXCall);
 };
 
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index aaf1333cf26eb123af2f7ba986d1cb7af55a72fe..0518937d6e839d140ff4683992ecf0b53390f1d9 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -278,7 +278,7 @@ IAXVoIPLink::answer(Call *call)
     Manager::instance().addStream(call->getCallId());
 
     mutexIAX_.enter();
-    call->answer();
+    static_cast<IAXCall*>(call)->answer();
     mutexIAX_.leave();
 
     call->setState(Call::ACTIVE);
diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index 0f54dd6621f4deb6b43d0c0415ca22fa70b0bb4e..1c9a547dbae39320d57e5db9855b06e606899662 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -386,15 +386,16 @@ bool
 Sdp::createOffer(const vector<int> &selectedCodecs,
                  const vector<map<string, string> > &videoCodecs)
 {
-    bool result = true;
     if (createLocalSession(selectedCodecs, videoCodecs) != PJ_SUCCESS) {
         ERROR("Failed to create initial offer");
-        result = false;
-    } else if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS) {
+        return false;
+    }
+
+    if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS) {
         ERROR("Failed to create an initial SDP negotiator");
-        result = false;
+        return false;
     }
-    return result;
+    return true;
 }
 
 void Sdp::receiveOffer(const pjmedia_sdp_session* remote,
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index f91a00af429ca5774a300594e371ce4aad36c342..8359bf2fe3e5d4eaea8879a8f5c2994a0ea0e6dd 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -62,10 +62,10 @@ SIPCall::~SIPCall()
     pj_pool_release(pool_);
 }
 
-void SIPCall::answer()
+void SIPCall::answer(bool needsSdp)
 {
     pjsip_tx_data *tdata;
-    if (pjsip_inv_answer(inv, PJSIP_SC_OK, NULL, NULL, &tdata) != PJ_SUCCESS)
+    if (pjsip_inv_answer(inv, PJSIP_SC_OK, NULL, needsSdp ? local_sdp_->getLocalSdpSession() : NULL, &tdata) != PJ_SUCCESS)
         throw std::runtime_error("Could not init invite request answer (200 OK)");
 
     if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h
index ba7e5e28780a4512579a2d42be89cfdd3486cd71..edd56b6afe15f5ad9871e012dd48b386cf5d1a65 100644
--- a/daemon/src/sip/sipcall.h
+++ b/daemon/src/sip/sipcall.h
@@ -100,6 +100,10 @@ class SIPCall : public Call {
             return pool_;
         }
 
+        // @param needsSdp: true if the invite was received without an SDP
+        // and thus one must been added, false otherwise
+        void answer(bool needsSdp);
+
         /**
          * The invite session to be reused in case of transfer
          */
@@ -114,8 +118,6 @@ class SIPCall : public Call {
         std::map<std::string, std::string>
         createHistoryEntry() const;
 
-        virtual void answer();
-
         NON_COPYABLE(SIPCall);
 
         /**
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 2c1182b2131396ae06ef66aed8f4654d53b299d8..6967efe2a4614f70c9ac2f86afc51fd4b6c26db6 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -902,7 +902,17 @@ SIPVoIPLink::answer(Call *call)
 {
     if (!call)
         return;
-    call->answer();
+
+    SIPCall *sipCall = static_cast<SIPCall*>(call);
+    bool needsSdp = false;
+    if (!sipCall->inv->neg) {
+        WARN("Negotiator is NULL, we've received an INVITE without an SDP");
+        pjmedia_sdp_session *dummy;
+        sdp_create_offer_cb(sipCall->inv, &dummy);
+        needsSdp = true;
+    }
+
+    sipCall->answer(needsSdp);
 }
 
 namespace {
@@ -946,8 +956,15 @@ SIPVoIPLink::hangup(const std::string& id)
 
     pjsip_tx_data *tdata = NULL;
 
+    const int status =
+        inv->state <= PJSIP_INV_STATE_EARLY and inv->role != PJSIP_ROLE_UAC ?
+                      PJSIP_SC_CALL_TSX_DOES_NOT_EXIST :
+        inv->state >= PJSIP_INV_STATE_DISCONNECTED ? PJSIP_SC_DECLINE :
+        0;
+
+
     // User hangup current call. Notify peer
-    if (pjsip_inv_end_session(inv, 0, NULL, &tdata) != PJ_SUCCESS || !tdata)
+    if (pjsip_inv_end_session(inv, status, NULL, &tdata) != PJ_SUCCESS || !tdata)
         return;
 
     // add contact header