From 7fb07ff36e727c1c2959f27e6207abcf13166829 Mon Sep 17 00:00:00 2001
From: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
Date: Tue, 20 Aug 2013 15:23:18 -0400
Subject: [PATCH] * sip: #28675: add correct contact header before sending OK

This ensures that SFLphone gets an ACK when doing calls with
sip2sip.info.
---
 daemon/src/call.h              |  7 ++++---
 daemon/src/sip/sip_utils.cpp   | 13 +++++++++++++
 daemon/src/sip/sip_utils.h     |  2 ++
 daemon/src/sip/sipaccount.cpp  |  5 ++++-
 daemon/src/sip/sipcall.cpp     | 10 ++++++++++
 daemon/src/sip/sipvoiplink.cpp | 17 ++---------------
 6 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/daemon/src/call.h b/daemon/src/call.h
index 0ba72776b5..504313be63 100644
--- a/daemon/src/call.h
+++ b/daemon/src/call.h
@@ -230,6 +230,10 @@ class Call : public Recordable {
 
         virtual bool toggleRecording();
 
+    protected:
+        /** Associate account ID */
+        std::string accountID_;
+
     private:
         std::string getTypeStr() const;
         /** Protect every attribute that can be changed by two threads */
@@ -255,9 +259,6 @@ class Call : public Recordable {
         /** Type of the call */
         CallType type_;
 
-        /** Associate account ID */
-        std::string accountID_;
-
         /** Disconnected/Progressing/Trying/Ringing/Connected */
         ConnectionState connectionState_;
 
diff --git a/daemon/src/sip/sip_utils.cpp b/daemon/src/sip/sip_utils.cpp
index 82a3b07dd3..27dcc33169 100644
--- a/daemon/src/sip/sip_utils.cpp
+++ b/daemon/src/sip/sip_utils.cpp
@@ -191,3 +191,16 @@ sip_utils::getIPList(const std::string &name)
     freeaddrinfo(result);
     return ipList;
 }
+
+void
+sip_utils::addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata)
+{
+    pj_str_t pjContact = pj_str((char*) contactStr.c_str());
+
+    pjsip_contact_hdr *contact = pjsip_contact_hdr_create(tdata->pool);
+    contact->uri = pjsip_parse_uri(tdata->pool, pjContact.ptr,
+                                   pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+    // remove old contact header (if present)
+    pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
+    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) contact);
+}
diff --git a/daemon/src/sip/sip_utils.h b/daemon/src/sip/sip_utils.h
index 91cf9e4b41..32d531db99 100644
--- a/daemon/src/sip/sip_utils.h
+++ b/daemon/src/sip/sip_utils.h
@@ -54,6 +54,8 @@ namespace sip_utils {
     std::string parseDisplayName(const char * buffer);
 
     std::vector<std::string> getIPList(const std::string &name);
+
+    void addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata);
 }
 
 #endif // SIP_UTILS_H_
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 8ba6bb6512..7d002cafb6 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -1103,12 +1103,15 @@ std::string SIPAccount::getContactHeader() const
 
     link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port);
 
-    if (!receivedParameter_.empty())
+    if (!receivedParameter_.empty()) {
         address = receivedParameter_;
+        DEBUG("Using received address %s", address.c_str());
+    }
 
     if (rPort_ != -1) {
         portstr << rPort_;
         port = portstr.str();
+        DEBUG("Using received port %s", port.c_str());
     }
 
     // UDP does not require the transport specification
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index 5a1b7a0eb9..ac896ee5b2 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -32,6 +32,8 @@
  */
 
 #include "sipcall.h"
+#include "sip_utils.h"
+#include "sipaccount.h"
 #include "logger.h" // for _debug
 #include "sdp.h"
 #include "manager.h"
@@ -73,6 +75,14 @@ void SIPCall::answer()
     if (pjsip_inv_answer(inv, PJSIP_SC_OK, NULL, !inv->neg ? local_sdp_->getLocalSdpSession() : NULL, &tdata) != PJ_SUCCESS)
         throw std::runtime_error("Could not init invite request answer (200 OK)");
 
+    SIPAccount *account = Manager::instance().getSipAccount(accountID_);
+
+    if (account == NULL)
+        throw std::runtime_error("Could not find account for this call");
+    // contactStr must stay in scope as long as tdata
+    const std::string contactStr(account->getContactHeader());
+    sip_utils::addContactHeader(contactStr, tdata);
+
     if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
         throw std::runtime_error("Could not send invite request answer (200 OK)");
 
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index f3d366b403..b8ba1d0b39 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -232,19 +232,6 @@ void updateSDPFromSTUN(SIPCall &call, SIPAccount &account, const SipTransport &t
     }
 }
 
-void
-addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata)
-{
-    pj_str_t pjContact = pj_str((char*) contactStr.c_str());
-
-    pjsip_contact_hdr *contact = pjsip_contact_hdr_create(tdata->pool);
-    contact->uri = pjsip_parse_uri(tdata->pool, pjContact.ptr,
-                                   pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
-    // remove old contact header (if present)
-    pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
-    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) contact);
-}
-
 pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 {
 
@@ -481,7 +468,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
         // contactStr must stay in scope as long as tdata
         const std::string contactStr(account->getContactHeader());
-        addContactHeader(contactStr, tdata);
+        sip_utils::addContactHeader(contactStr, tdata);
 
         if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS) {
             ERROR("Could not send msg for invite");
@@ -1096,7 +1083,7 @@ SIPVoIPLink::hangup(const std::string& id, int reason)
 
     // contactStr must stay in scope as long as tdata
     const std::string contactStr(account->getContactHeader());
-    addContactHeader(contactStr, tdata);
+    sip_utils::addContactHeader(contactStr, tdata);
 
     if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
         return;
-- 
GitLab