Commit a3a5311f authored by Guillaume Roguez's avatar Guillaume Roguez Committed by gerrit2

sip: factorize dialog and invite session creation

SIP dialog and invite session creation code is duplicated
in SIPAccount and RingAccount call creation code.
This patch factorizes this code by moving identical parts
into SIPAccountBase base class.
The new common method is now CreateClientDialogAndInvite().

By the way notice that previous duplicated code was locked
the dialog. This extra lock it uneeded and wrong:
- wrong because pjsip_dlg_inc_lock() was used, but it should
be used only temporarily [1]
- uneeded as the dialog session counter is increased by the invite
session itself
The correct way is to call pjsip_dlg_inc_session if we need long
lock, that not our case here as we manage the invite session.

[1] http://www.pjsip.org/pjsip/docs/html/group__PJSIP__DIALOG.htm#ga5d87304615303ffbe20a09e0a3ff59df)

Change-Id: I8c2042b4c0278315cf76ea38affa8b90cab5cc7f
Tuleap: #64
parent 3ae6811c
......@@ -592,30 +592,13 @@ RingAccount::SIPStartCall(const std::shared_ptr<SIPCall>& call, IpAddr target)
(int)pjContact.slen, pjContact.ptr, from.c_str(), toUri.c_str(),
(int)pjTarget.slen, pjTarget.ptr);
pjsip_dialog *dialog = NULL;
if (pjsip_dlg_create_uac(pjsip_ua_instance(), &pjFrom, &pjContact, &pjTo, &pjTarget, &dialog) != PJ_SUCCESS) {
RING_ERR("Unable to create SIP dialogs for user agent client when "
"calling %s", toUri.c_str());
return false;
}
pj_str_t subj_hdr_name = CONST_PJ_STR("Subject");
pjsip_hdr* subj_hdr = (pjsip_hdr*) pjsip_parse_hdr(dialog->pool, &subj_hdr_name, (char *) "Phone call", 10, NULL);
pj_list_push_back(&dialog->inv_hdr, subj_hdr);
pjsip_inv_session* inv = nullptr;
if (pjsip_inv_create_uac(dialog, call->getSDP().getLocalSdpSession(), 0, &inv) != PJ_SUCCESS) {
RING_ERR("Unable to create invite session for user agent client");
auto local_sdp = call->getSDP().getLocalSdpSession();
pjsip_dialog* dialog {nullptr};
pjsip_inv_session* inv {nullptr};
if (!CreateClientDialogAndInvite(&pjFrom, &pjContact, &pjTo, &pjTarget, local_sdp, &dialog, &inv))
return false;
}
if (!inv) {
RING_ERR("Call invite is not initialized");
return PJ_FALSE;
}
pjsip_dlg_inc_lock(inv->dlg);
inv->mod_data[link_->getModId()] = call.get();
call->inv.reset(inv);
......
......@@ -339,31 +339,12 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
RING_DBG("contact header: %.*s / %s -> %s",
(int)pjContact.slen, pjContact.ptr, from.c_str(), toUri.c_str());
pjsip_dialog *dialog = NULL;
if (pjsip_dlg_create_uac(pjsip_ua_instance(), &pjFrom, &pjContact, &pjTo, NULL, &dialog) != PJ_SUCCESS) {
RING_ERR("Unable to create SIP dialogs for user agent client when "
"calling %s", toUri.c_str());
auto local_sdp = call->getSDP().getLocalSdpSession();
pjsip_dialog* dialog {nullptr};
pjsip_inv_session* inv {nullptr};
if (!CreateClientDialogAndInvite(&pjFrom, &pjContact, &pjTo, nullptr, local_sdp, &dialog, &inv))
return false;
}
auto subj_hdr_name = CONST_PJ_STR("Subject");
pjsip_hdr* subj_hdr = (pjsip_hdr*) pjsip_parse_hdr(dialog->pool, &subj_hdr_name, (char *) "Phone call", 10, NULL);
pj_list_push_back(&dialog->inv_hdr, subj_hdr);
pjsip_inv_session* inv = nullptr;
if (pjsip_inv_create_uac(dialog, call->getSDP().getLocalSdpSession(), 0, &inv) != PJ_SUCCESS) {
RING_ERR("Unable to create invite session for user agent client");
return false;
}
if (!inv) {
RING_ERR("Call invite is not initialized");
return PJ_FALSE;
}
pjsip_dlg_inc_lock(inv->dlg);
inv->mod_data[link_->getModId()] = call.get();
call->inv.reset(inv);
......
......@@ -40,6 +40,7 @@
#include "client/ring_signal.h"
#include "string_utils.h"
#include "fileutils.h"
#include "sip_utils.h"
#include <type_traits>
......@@ -53,6 +54,43 @@ SIPAccountBase::SIPAccountBase(const std::string& accountID)
SIPAccountBase::~SIPAccountBase() {}
bool
SIPAccountBase::CreateClientDialogAndInvite(const pj_str_t* from,
const pj_str_t* contact,
const pj_str_t* to,
const pj_str_t* target,
const pjmedia_sdp_session* local_sdp,
pjsip_dialog** dlg,
pjsip_inv_session** inv)
{
if (pjsip_dlg_create_uac(pjsip_ua_instance(), from, contact, to, target, dlg) != PJ_SUCCESS) {
RING_ERR("Unable to create SIP dialogs for user agent client when calling %s", to->ptr);
return false;
}
auto dialog = *dlg;
{
// lock dialog until invite session creation; this one will own the dialog after
sip_utils::PJDialogLock dlg_lock {dialog};
// Append "Subject: Phone Call" header
auto subj_hdr_name = sip_utils::CONST_PJ_STR("Subject");
auto subj_hdr = reinterpret_cast<pjsip_hdr*>(pjsip_parse_hdr(dialog->pool,
&subj_hdr_name,
const_cast<char *>("Phone call"),
10, nullptr));
pj_list_push_back(&dialog->inv_hdr, subj_hdr);
if (pjsip_inv_create_uac(dialog, local_sdp, 0, inv) != PJ_SUCCESS) {
RING_ERR("Unable to create invite session for user agent client");
return false;
}
}
return true;
}
void
SIPAccountBase::flush()
{
......
......@@ -41,6 +41,10 @@
#include <map>
#include <memory>
struct pjsip_dialog;
struct pjsip_inv_session;
struct pjmedia_sdp_session;
namespace ring {
namespace Conf {
......@@ -145,6 +149,19 @@ public:
return false;
}
/**
* Create UAC attached dialog and invite session
* @return true if success. false if failure and dlg and inv pointers
* should not be considered as valid.
*/
bool CreateClientDialogAndInvite(const pj_str_t* from,
const pj_str_t* contact,
const pj_str_t* to,
const pj_str_t* target,
const pjmedia_sdp_session* local_sdp,
pjsip_dialog** dlg,
pjsip_inv_session** inv);
/**
* Get the local interface name on which this account is bound.
*/
......
......@@ -1101,7 +1101,6 @@ SIPCall::InvSessionDeleter::operator ()(pjsip_inv_session* inv) const noexcept
// prevent this from getting accessed in callbacks
// RING_WARN: this is not thread-safe!
inv->mod_data[getSIPVoIPLink()->getModId()] = nullptr;
pjsip_dlg_dec_lock(inv->dlg);
}
bool
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment