Commit 34075aa9 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#3014] Don't delete call in call_state_cahnged when refusing an incoming call

This is done in SIPVoipLink::refuse method
parent e03caede
......@@ -77,14 +77,14 @@ CallManager::placeCallFirstAccount (const std::string& callID,
void
CallManager::refuse (const std::string& callID)
{
_debug ("CallManager::refuse received");
_debug ("CallManager: refuse received");
Manager::instance().refuseCall (callID);
}
void
CallManager::accept (const std::string& callID)
{
_debug ("CallManager::accept received");
_debug ("CallManager: accept received");
Manager::instance().answerCall (callID);
}
......
......@@ -486,6 +486,8 @@ bool ManagerImpl::cancelCall (const CallID& id) {
AccountID accountid;
bool returnValue;
_debug("Manager: Cancel call");
stopTone();
/* Direct IP to IP call */
......@@ -694,6 +696,8 @@ bool ManagerImpl::refuseCall (const CallID& id) {
AccountID accountid;
bool returnValue;
_debug("Manager: Refuse call %s", id.c_str());
CallID current_call_id = getCurrentCallId();
stopTone();
......@@ -703,12 +707,14 @@ bool ManagerImpl::refuseCall (const CallID& id) {
// AudioLayer* audiolayer = getAudioDriver();
if (nbCalls <= 1) {
_debug (" hangupCall: stop audio stream, ther is only %i call(s) remaining", nbCalls);
_debug ("Manager: Stop audio stream, ther is only %i call(s) remaining", nbCalls);
AudioLayer* audiolayer = getAudioDriver();
audiolayer->stopStream();
}
_debug("OK");
/* Direct IP to IP call */
if (getConfigFromCall(id) == Call::IPtoIP) {
......@@ -720,7 +726,7 @@ bool ManagerImpl::refuseCall (const CallID& id) {
accountid = getAccountFromCall(id);
if (accountid == AccountNULL) {
_debug ("! Manager OffHold Call: Call doesn't exists");
_warn ("Manager: Call doesn't exists");
return false;
}
......@@ -728,6 +734,7 @@ bool ManagerImpl::refuseCall (const CallID& id) {
removeCallAccount(id);
}
_debug("OK");
// if the call was outgoing or established, we didn't refuse it
// so the method did nothing
......@@ -736,9 +743,6 @@ bool ManagerImpl::refuseCall (const CallID& id) {
if (_dbus)
_dbus->getCallManager()->callStateChanged(id, "HUNGUP");
// if(current_call_id.compare("") != 0)
// switchCall ("");
}
return returnValue;
......@@ -1518,18 +1522,24 @@ bool ManagerImpl::incomingCallWaiting () {
}
void ManagerImpl::addWaitingCall (const CallID& id) {
ost::MutexLock m(_waitingCallMutex);
_waitingCall.insert(id);
_nbIncomingWaitingCall++;
_info("Manager: Add waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall);
}
void ManagerImpl::removeWaitingCall (const CallID& id) {
ost::MutexLock m(_waitingCallMutex);
// should return more than 1 if it erase a call
if (_waitingCall.erase(id)) {
_nbIncomingWaitingCall--;
}
_info("Manager: Remove waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall);
}
bool ManagerImpl::isWaitingCall (const CallID& id) {
......@@ -1547,29 +1557,29 @@ bool ManagerImpl::isWaitingCall (const CallID& id) {
////////////////////////////////////////////////////////////////////////////////
// SipEvent Thread
bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) {
PulseLayer *pulselayer;
std::string from, number, display_name, display;
if(!call)
_error("Manager: Error: no call at this point");
stopTone();
_debug ("Incoming call %s for account %s", call->getCallId().data(), accountId.c_str());
_debug ("Manager: Incoming call %s for account %s", call->getCallId().data(), accountId.c_str());
associateCallToAccount(call->getCallId(), accountId);
// If account is null it is an ip to ip call
if (accountId == AccountNULL) {
associateConfigToCall(call->getCallId(), Call::IPtoIP);
} else {
}
else {
// strip sip: which is not required and bring confusion with ip to ip calls
// when placing new call from history (if call is IAX, do nothing)
std::string peerNumber = call->getPeerNumber();
int startIndex = peerNumber.find("sip:");
// if "sip:" is found => it is not an IAX call
if (startIndex != (int) string::npos) {
std::string strippedPeerNumber = peerNumber.substr(startIndex + 4);
call->setPeerNumber(strippedPeerNumber);
......@@ -1577,32 +1587,23 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) {
}
_debug ("ManagerImpl::incomingCall :: hasCurrentCall() %i ", hasCurrentCall());
if (!hasCurrentCall()) {
_debug ("Manager: Has no current call");
call->setConnectionState(Call::Ringing);
ringtone();
// switchCall (call->getCallId());
}
/*
else {
addWaitingCall(call->getCallId());
}
*/
else {
_debug ("Manager: has current call");
}
addWaitingCall(call->getCallId());
from = call->getPeerName();
number = call->getPeerNumber();
display_name = call->getDisplayName();
// _debug( "incomingCall from: %s, number: %s, display_name: %s", from.c_str(), number.c_str(), display_name.c_str());
if (from != "" && number != "") {
from.append(" <");
from.append(number);
......@@ -1613,33 +1614,15 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) {
from.append(">");
}
/*
CallIDSet::iterator iter = _waitingCall.begin();
while (iter != _waitingCall.end()) {
CallID ident = *iter;
_debug("ManagerImpl::incomingCall :: CALL iteration: %s ",ident.c_str());
++iter;
}
*/
/* Broadcast a signal over DBus */
_debug ("From: %s, Number: %s, DisplayName: %s", from.c_str(), number.c_str(), display_name.c_str());
_debug ("Manager: From: %s, Number: %s, Display Name: %s", from.c_str(), number.c_str(), display_name.c_str());
display = display_name;
display.append(" ");
display.append(from);
if (_dbus)
_dbus->getCallManager()->incomingCall(accountId, call->getCallId(),
display.c_str());
//if (_dbus) _dbus->getCallManager()->callStateChanged(call->getCallId(), "INCOMING");
if (_audiodriver->getLayerType() == PULSEAUDIO) {
pulselayer = dynamic_cast<PulseLayer *> (getAudioDriver());
}
_dbus->getCallManager()->incomingCall(accountId, call->getCallId(), display.c_str());
return true;
}
......@@ -1916,7 +1899,8 @@ void ManagerImpl::ringback () {
* Multi Thread
*/
void ManagerImpl::ringtone () {
_debug ("ManagerImpl::ringtone");
_debug ("Manager: Start ringtone");
std::string ringchoice;
AudioLayer *audiolayer;
AudioCodec *codecForTone;
......@@ -1925,7 +1909,7 @@ void ManagerImpl::ringtone () {
if (isRingtoneEnabled()) {
_debug (" Tone is enabled");
_debug ("Manager: Tone is enabled");
//TODO Comment this because it makes the daemon crashes since the main thread
//synchronizes the ringtone thread.
......@@ -1940,10 +1924,12 @@ void ManagerImpl::ringtone () {
audiolayer = getAudioDriver();
layer = audiolayer->getLayerType();
if (audiolayer == 0)
if (!audiolayer) {
_error("Manager: Error: no audio layer in ringtone");
return;
}
layer = audiolayer->getLayerType();
samplerate = audiolayer->getSampleRate();
......@@ -4068,18 +4054,19 @@ ManagerImpl::getAccount (const AccountID& accountID) {
AccountID ManagerImpl::getAccountIdFromNameAndServer (
const std::string& userName, const std::string& server) {
AccountMap::iterator iter;
SIPAccount *account;
_debug ("getAccountIdFromNameAndServer : username = %s , server = %s", userName.c_str(), server.c_str());
_info ("Manager : username = %s , server = %s", userName.c_str(), server.c_str());
// Try to find the account id from username and server name by full match
for (iter = _accountMap.begin(); iter != _accountMap.end(); ++iter) {
_debug ("for : account = %s", iter->first.c_str());
account = dynamic_cast<SIPAccount *> (iter->second);
if (account != NULL) {
if (account->fullMatch(userName, server)) {
_debug ("Matching accountId in request is a fullmatch");
_debug ("Manager: Matching account id in request is a fullmatch %s@%s", userName.c_str(), server.c_str());
return iter->first;
}
}
......@@ -4091,7 +4078,7 @@ AccountID ManagerImpl::getAccountIdFromNameAndServer (
if (account != NULL) {
if (account->hostnameMatch(server)) {
_debug ("Matching accountId in request with hostname");
_debug ("Manager: Matching account id in request with hostname %s", server.c_str());
return iter->first;
}
}
......@@ -4103,12 +4090,14 @@ AccountID ManagerImpl::getAccountIdFromNameAndServer (
if (account != NULL) {
if (account->userMatch(userName)) {
_debug ("Matching accountId in request with username");
_debug ("Manager: Matching account id in request with username %s", userName.c_str());
return iter->first;
}
}
}
_debug ("Manager: Username %s or server %s doesn't match any account, using IP2IP", userName.c_str(), server.c_str());
// Failed again! return AccountNULL
return AccountNULL;
}
......@@ -4232,7 +4221,7 @@ bool ManagerImpl::associateConfigToCall (const CallID& callID,
if (getConfigFromCall(callID) == CallConfigNULL) { // nothing with the same ID
_callConfigMap[callID] = config;
_debug ("Associate Call %s with config %i", callID.data(), config);
_debug ("Manager: Associate call %s with config %i", callID.c_str(), config);
return true;
} else {
return false;
......
......@@ -33,17 +33,19 @@ SIPCall::SIPCall (const CallID& id, Call::CallType type, pj_pool_t *pool) : Call
, _invSession (NULL)
, _local_sdp (0)
{
_debug ("SIPCall: Create new call %s", id.c_str());
_local_sdp = new Sdp (pool);
_debug ("SIPCALL::Constructor for this class is called ");
}
SIPCall::~SIPCall()
{
_debug ("SIPCall: Delete call");
delete _audiortp;
_audiortp = 0;
delete _local_sdp;
_local_sdp = 0;
_debug ("SIPCALL::Destructor for this class is called ");
}
......
......@@ -352,6 +352,7 @@ SIPVoIPLink::terminateSIPCall()
void
SIPVoIPLink::terminateOneCall (const CallID& id)
{
_debug("UserAgent: Terminate call %s", id.c_str());
SIPCall *call = getSIPCall (id);
......@@ -396,7 +397,7 @@ std::string SIPVoIPLink::getInterfaceAddrFromName(std::string ifaceName) {
struct in_addr *addr_in;
if((fd = socket (AF_INET, SOCK_DGRAM,0)) < 0)
_debug("UserAgent: getInterfaceAddrFromName error could not open socket\n");
_error("UserAgent: Error: could not open socket");
memset (&ifr, 0, sizeof (struct ifreq));
......@@ -404,7 +405,7 @@ std::string SIPVoIPLink::getInterfaceAddrFromName(std::string ifaceName) {
ifr.ifr_addr.sa_family = AF_INET;
if((err = ioctl(fd, SIOCGIFADDR, &ifr)) < 0)
_debug("UserAgent: getInterfaceAddrFromName use default interface (0.0.0.0)\n");
_debug("UserAgent: Use default interface (0.0.0.0)");
saddr_in = (struct sockaddr_in *)&ifr.ifr_addr;
addr_in = &(saddr_in->sin_addr);
......@@ -974,15 +975,15 @@ SIPVoIPLink::peerHungup (const CallID& id)
bool
SIPVoIPLink::cancel (const CallID& id)
{
_info ("UserAgent: Cancel call %s", id.c_str());
SIPCall* call = getSIPCall (id);
if (call==0) {
_debug ("! SIP Error: Call doesn't exist");
if (!call) {
_warn("UserAgent: Error: Call doesn't exist");
return false;
}
_debug ("- SIP Action: Cancel call %s [cid: %3d]", id.data(), call->getCid());
terminateOneCall (id);
removeCall (id);
......@@ -1203,17 +1204,18 @@ SIPVoIPLink::refuse (const CallID& id)
pj_status_t status;
pjsip_tx_data *tdata;
_debug("UserAgent: Refuse call %s", id.c_str());
call = getSIPCall (id);
if (call==0) {
_debug ("Call doesn't exist");
_error ("UserAgent: Error: Call doesn't exist");
return false;
}
// can't refuse outgoing call or connected
if (!call->isIncoming() || call->getConnectionState() == Call::Connected) {
_debug ("It's not an incoming call, or it's already answered");
_debug ("UserAgent: Call %s is not in state incoming, or is already answered");
return false;
}
......@@ -1232,6 +1234,8 @@ SIPVoIPLink::refuse (const CallID& id)
terminateOneCall (id);
_debug("UserAgent: Refuse call completed");
return true;
}
......@@ -1499,7 +1503,7 @@ void
SIPVoIPLink::SIPCallServerFailure (SIPCall *call)
{
if (call != 0) {
_debug ("Server error!");
_error ("UserAgent: Error: Server error!");
CallID id = call->getCallId();
Manager::instance().callFailure (id);
terminateOneCall (id);
......@@ -2987,7 +2991,7 @@ void set_voicemail_info (AccountID account, pjsip_msg_body *body)
void SIPVoIPLink::handle_reinvite (SIPCall *call)
{
_debug ("UserAgent: handle_reinvite");
_debug ("UserAgent: Handle reinvite");
/*
// Close the previous RTP session
call->getAudioRtp()->stop ();
......@@ -3010,7 +3014,7 @@ void SIPVoIPLink::handle_reinvite (SIPCall *call)
// 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 to state %s", invitationStateMap[inv->state]);
_debug ("UserAgent: Call state changed to %s", invitationStateMap[inv->state]);
pjsip_rx_data *rdata;
pj_status_t status;
......@@ -3055,7 +3059,6 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE;
switch (call->getInvSession()->state) {
// switch (inv->state) {
case PJSIP_INV_STATE_NULL:
......@@ -3094,9 +3097,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
pjsip_tx_data *tdata;
pj_status_t status;
status = pjsip_xfer_notify (call->getXferSub(),
ev_state, st_code,
NULL, &tdata);
status = pjsip_xfer_notify (call->getXferSub(), ev_state, st_code, NULL, &tdata);
if (status != PJ_SUCCESS) {
_debug ("UserAgent: Unable to create NOTIFY -- %d", status);
......@@ -3170,9 +3171,12 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
break;
case PJSIP_SC_NOT_FOUND: /* peer not found */
case PJSIP_SC_DECLINE:
_debug("UserAgent: Call %s is declined", call->getCallId().c_str());
// if (inv->role == PJSIP_ROLE_UAS)
break;
case PJSIP_SC_DECLINE: /* We have been ignored */
case PJSIP_SC_NOT_FOUND: /* peer not found */
case PJSIP_SC_REQUEST_TIMEOUT: /* request timeout */
......@@ -3187,6 +3191,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
case PJSIP_SC_FORBIDDEN:
case PJSIP_SC_REQUEST_PENDING:
accId = Manager::instance().getAccountFromCall (call->getCallId());
link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId));
......@@ -3207,7 +3212,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e)
// 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 ("UserAgent: Call on media update");
_debug ("UserAgent: Call media update");
const pjmedia_sdp_session *local_sdp;
const pjmedia_sdp_session *remote_sdp;
......@@ -3337,8 +3342,9 @@ void call_on_forked (pjsip_inv_session *inv, pjsip_event *e)
void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
{
_debug("UserAgent: Transaction changed to state %s", transactionStateMap[tsx->state]);
assert(tsx);
_debug("UserAgent: Transaction changed to state %s", transactionStateMap[tsx->state]);
if (tsx->role==PJSIP_ROLE_UAS && tsx->state==PJSIP_TSX_STATE_TRYING &&
pjsip_method_cmp (&tsx->method, &pjsip_refer_method) ==0) {
......@@ -3348,10 +3354,14 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_
if (e && e->body.rx_msg.rdata) {
_debug("Event");
pjsip_tx_data* t_data;
pjsip_rx_data* r_data = e->body.rx_msg.rdata;
if (r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) {
if (r_data && r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) {
_debug("R_data");
std::string method_info = "INFO";
std::string method_notify = "NOTIFY";
......@@ -3373,6 +3383,8 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_
}
}
}
_debug("OK: ransaction changed to state");
}
void regc_cb (struct pjsip_regc_cbparam *param)
......@@ -3502,18 +3514,18 @@ mod_on_rx_request (pjsip_rx_data *rdata)
std::string method_name;
std::string request;
_info("UserAgent: Receiving REQUEST using transport: %s %s (refcnt=%d)",
rdata->tp_info.transport->obj_name,
rdata->tp_info.transport->info,
(int)pj_atomic_get(rdata->tp_info.transport->ref_cnt));
// No need to go any further on incoming ACK
if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
_info("UserAgent: received an ACK");
return true;
}
// Handle the incoming call invite in this function
_info("UserAgent: Receiving REQUEST using transport: %s %s (refcnt=%d)",
rdata->tp_info.transport->obj_name,
rdata->tp_info.transport->info,
(int)pj_atomic_get(rdata->tp_info.transport->ref_cnt));
/* First, let's got the username and server name from the invite.
* We will use them to detect which account is the callee.
*/
......@@ -3523,13 +3535,10 @@ mod_on_rx_request (pjsip_rx_data *rdata)
userName = std::string (sip_uri->user.ptr, sip_uri->user.slen);
server = std::string (sip_uri->host.ptr, sip_uri->host.slen);
_debug ("UserAgent: mod_on_rx_request: %s@%s", userName.c_str(), server.c_str());
// Get the account id of callee from username and server
account_id = Manager::instance().getAccountIdFromNameAndServer (userName, server);
/* If we don't find any account to receive the call */
if (account_id == AccountNULL) {
_debug ("UserAgent: Username %s doesn't match any account, using IP2IP!",userName.c_str());
}
......@@ -3562,7 +3571,7 @@ mod_on_rx_request (pjsip_rx_data *rdata)
displayName = std::string ("");
}
_debug ("UserAgent: The receiver is : %s@%s", userName.data(), server.data());
_debug ("UserAgent: The receiver is: %s@%s", userName.data(), server.data());
_debug ("UserAgent: The callee account id is %s", account_id.c_str());
/* Now, it is the time to find the information of the caller */
......@@ -3580,6 +3589,7 @@ mod_on_rx_request (pjsip_rx_data *rdata)
// Get the server voicemail notification
// Catch the NOTIFY message
if (rdata->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) {
method_name = "NOTIFY";
// Retrieve all the message. Should contains only the method name but ...
request = rdata->msg_info.msg->line.req.method.name.ptr;
......@@ -3616,10 +3626,10 @@ mod_on_rx_request (pjsip_rx_data *rdata)
get_remote_sdp_from_offer (rdata, &r_sdp);
if(account->getActiveCodecs().empty()) {
_warn ("UserAgent: Error: No active codec");
pj_strdup2 (_pool, &reason, "no active codec");
_warn ("UserAgent: Error: No active codec");
pj_strdup2 (_pool, &reason, "no active codec");
pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE ,
&reason, NULL, NULL);
&reason, NULL, NULL);
return true;
}
......@@ -3658,13 +3668,14 @@ mod_on_rx_request (pjsip_rx_data *rdata)
id = Manager::instance().getNewCallID();
call = new SIPCall (id, Call::Incoming, _pool);
/* If an error occured at the call creation */
// If an error occured at the call creation
if (!call) {
_warn("UserAgent: Error: Unable to create an incoming call");
pj_strdup2 (_pool, &reason, "unable to create an incoming call");
pj_strdup2 (_pool, &reason, "unable to create an incoming call");
pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR,
&reason, NULL, NULL);
return false;
return false;
}
std::string addrToUse, addrSdp ="0.0.0.0";
......@@ -3676,17 +3687,17 @@ mod_on_rx_request (pjsip_rx_data *rdata)
// May use the published address as well
addrToUse = SIPVoIPLink::instance("")->getInterfaceAddrFromName(account->getLocalInterface ());
account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = addrToUse;
// Set the appropriate transport to have the right VIA header
link->init_transport_selector (account->getAccountTransport (), &tp);
account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = addrToUse;
// Set the appropriate transport to have the right VIA header
link->init_transport_selector (account->getAccountTransport (), &tp);
if(account->getAccountTransport()) {
if(account->getAccountTransport()) {
_debug("UserAgent: Process INVITE request using transport: %s %s (refcnt=%i)",
account->getAccountTransport()->obj_name,
account->getAccountTransport()->info,
(int)pj_atomic_get(account->getAccountTransport()->ref_cnt));
}
_debug("UserAgent: SIP transport for this account: %s %s (refcnt=%i)",
account->getAccountTransport()->obj_name,
account->getAccountTransport()->info,
(int)pj_atomic_get(account->getAccountTransport()->ref_cnt));
}
}
......@@ -3707,22 +3718,6 @@ mod_on_rx_request (pjsip_rx_data *rdata)
call->initRecFileName();