Commit a5ffa4fa authored by Guillaume Roguez's avatar Guillaume Roguez Committed by Tristan Matthews

daemon: move hangup API to Call class

Refs #51555

Change-Id: Id3efff03eacd14415bc5d91691e7098ffd81cb91
parent 83f9a6ff
......@@ -239,6 +239,12 @@ class Call : public Recordable {
virtual VoIPLink* getVoIPLink() const = 0;
/**
* Hang up the call
* @param reason
*/
virtual void hangup(int reason) = 0;
private:
bool validTransition(CallState newState);
......
......@@ -132,3 +132,15 @@ void IAXCall::answer()
VoIPLink*
IAXCall::getVoIPLink() const
{ return link_; }
void
IAXCall::hangup(int reason UNUSED)
{
Manager::instance().getMainBuffer().unBindAll(getCallId());
std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
iax_hangup(session, (char*) "Dumped Call");
session = nullptr;
link_->removeIaxCall(getCallId());
}
......@@ -80,6 +80,8 @@ class IAXCall : public Call {
VoIPLink* getVoIPLink() const;
void hangup(int reason);
private:
void answer();
......
......@@ -330,27 +330,6 @@ IAXVoIPLink::answer(Call *call)
Manager::instance().getMainBuffer().flushAllBuffers();
}
void
IAXVoIPLink::hangup(const std::string& id, int reason UNUSED)
{
Manager::instance().getMainBuffer().unBindAll(id);
{
std::lock_guard<std::mutex> lock(iaxCallMapMutex_);
auto call = getIAXCall(id);
if (!call)
throw VoipLinkException("Could not find call");
{
std::lock_guard<std::mutex> lock(mutexIAX);
iax_hangup(call->session, (char*) "Dumped Call");
}
call->session = NULL;
}
removeIaxCall(id);
}
void
IAXVoIPLink::peerHungup(const std::string& id)
......
......@@ -127,12 +127,6 @@ class IAXVoIPLink : public VoIPLink {
*/
virtual void answer(Call *c);
/**
* Hangup a call
* @param id The ID of the call
*/
virtual void hangup(const std::string& id, int reason);
/**
* Peer Hungup a call
* @param id The ID of the call
......
......@@ -487,7 +487,7 @@ bool ManagerImpl::hangupCall(const std::string& callId)
try {
if (auto call = getCallFromCallID(callId)) {
history_.addCall(call.get(), preferences.getHistoryLimit());
call->getVoIPLink()->hangup(callId, 0);
call->hangup(0);
checkAudio();
saveHistory();
}
......
......@@ -225,3 +225,63 @@ SIPCall::onhold()
VoIPLink*
SIPCall::getVoIPLink() const
{ return &SIPVoIPLink::instance(); }
void
SIPCall::hangup(int reason)
{
const std::string account_id(getAccountId());
SIPAccount *account = Manager::instance().getSipAccount(account_id);
if (not account)
throw VoipLinkException("Could not find account for this call");
if (not inv)
throw VoipLinkException("No invite session for this call");
pjsip_route_hdr *route = inv->dlg->route_set.next;
while (route and route != &inv->dlg->route_set) {
char buf[1024];
int printed = pjsip_hdr_print_on(route, buf, sizeof(buf));
if (printed >= 0) {
buf[printed] = '\0';
DEBUG("Route header %s", buf);
}
route = route->next;
}
pjsip_tx_data *tdata = NULL;
const int status = reason ? reason :
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, status, NULL, &tdata) != PJ_SUCCESS || !tdata)
return;
// contactStr must stay in scope as long as tdata
const pj_str_t contactStr(account->getContactHeader());
sip_utils::addContactHeader(&contactStr, tdata);
if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
return;
auto& siplink = SIPVoIPLink::instance();
// Make sure user data is NULL in callbacks
inv->mod_data[siplink.getMod()->id] = NULL;
// Stop all RTP streams
if (Manager::instance().isCurrentCall(getCallId())) {
getAudioRtp().stop();
#ifdef SFL_VIDEO
getVideoRtp().stop();
#endif
}
siplink.removeSipCall(getCallId());
}
......@@ -117,6 +117,8 @@ class SIPCall : public Call {
VoIPLink* getVoIPLink() const;
void hangup(int reason);
private:
// override of Call::createHistoryEntry
......
......@@ -1059,64 +1059,6 @@ stopRtpIfCurrent(const std::string &id, SIPCall &call)
}
}
void
SIPVoIPLink::hangup(const std::string& id, int reason)
{
auto call = getSipCall(id);
if (!call)
return;
std::string account_id(call->getAccountId());
SIPAccount *account = Manager::instance().getSipAccount(account_id);
if (account == NULL)
throw VoipLinkException("Could not find account for this call");
pjsip_inv_session *inv = call->inv;
if (inv == NULL)
throw VoipLinkException("No invite session for this call");
pjsip_route_hdr *route = inv->dlg->route_set.next;
while (route and route != &inv->dlg->route_set) {
char buf[1024];
int printed = pjsip_hdr_print_on(route, buf, sizeof(buf));
if (printed >= 0) {
buf[printed] = '\0';
DEBUG("Route header %s", buf);
}
route = route->next;
}
pjsip_tx_data *tdata = NULL;
const int status = reason ? reason :
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, status, NULL, &tdata) != PJ_SUCCESS || !tdata)
return;
// contactStr must stay in scope as long as tdata
const pj_str_t contactStr(account->getContactHeader());
sip_utils::addContactHeader(&contactStr, tdata);
if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
return;
// Make sure user data is NULL in callbacks
inv->mod_data[mod_ua_.id] = NULL;
stopRtpIfCurrent(id, *call);
removeSipCall(id);
}
void
SIPVoIPLink::peerHungup(const std::string& id)
{
......@@ -1806,9 +1748,9 @@ sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
WARN("Could not negotiate offer");
const std::string callID(call->getCallId());
SIPVoIPLink::instance().hangup(callID, reason);
// call is now a dangling pointer after calling hangup
call = 0;
call->hangup(reason);
// This will probably invoke call's destructor
call = nullptr;
Manager::instance().callFailure(callID);
return;
}
......
......@@ -165,12 +165,6 @@ class SIPVoIPLink : public VoIPLink {
*/
virtual void answer(Call *c);
/**
* Hang up the call
* @param id The call identifier
*/
virtual void hangup(const std::string& id, int reason);
/**
* Hang up the call
* @param id The call identifier
......
......@@ -99,12 +99,6 @@ class VoIPLink {
*/
virtual void answer(Call *c) = 0;
/**
* Hang up a call
* @param id The call identifier
*/
virtual void hangup(const std::string &id, int reason) = 0;
/**
* Peer Hung up a call
* @param id The call identifier
......
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