Commit c5f31580 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #6554: refactoring, fix memleaks in sipvoiplink

parent 5f984885
......@@ -65,13 +65,12 @@ void AudioCodecFactory::setDefaultOrder()
std::string
AudioCodecFactory::getCodecName (AudioCodecType payload)
{
std::string resNull = "";
CodecsMap::iterator iter = _CodecsMap.find (payload);
if (iter!=_CodecsMap.end())
return (iter->second->getMimeSubtype());
return resNull;
return "";
}
sfl::Codec*
......
......@@ -31,11 +31,14 @@
#include "iaxvoiplink.h"
#include "iaxcall.h"
#include "eventthread.h"
#include "im/InstantMessaging.h"
#include "iaxaccount.h"
#include "manager.h"
#include "hooks/urlhook.h"
#include "audio/audiolayer.h"
#include "audio/samplerateconverter.h"
#include <math.h>
#include <cmath>
#include <dlfcn.h>
#define IAX_BLOCKING 1
......@@ -546,10 +549,10 @@ IAXVoIPLink::sendTextMessage (sfl::InstantMessaging *module,
std::string
IAXVoIPLink::getCurrentCodecName(Call *c)
IAXVoIPLink::getCurrentCodecName(Call *c) const
{
IAXCall *call = (IAXCall*)c;
sfl::Codec *audioCodec = call->getAudioCodecFactory().getCodec (call->getAudioCodec());
IAXCall *call = dynamic_cast<IAXCall*>(c);
sfl::Codec *audioCodec = call->getAudioCodecFactory().getCodec(call->getAudioCodec());
return audioCodec ? audioCodec->getMimeSubtype() : "";
}
......@@ -557,15 +560,9 @@ IAXVoIPLink::getCurrentCodecName(Call *c)
bool
IAXVoIPLink::iaxOutgoingInvite (IAXCall* call)
{
struct iax_session *newsession;
ost::MutexLock m (_mutexIAX);
std::string username, strNum;
char *lang=NULL;
int wait, audio_format_preferred, audio_format_capability;
IAXAccount *account;
newsession = iax_session_new();
iax_session *newsession = iax_session_new();
if (!newsession) {
_debug ("IAX Error: Can't make new session for a new call");
......@@ -574,17 +571,17 @@ IAXVoIPLink::iaxOutgoingInvite (IAXCall* call)
call->setSession (newsession);
account = getAccountPtr();
username = account->getUsername();
strNum = username + ":" + account->getPassword() + "@" + account->getHostname() + "/" + call->getPeerNumber();
IAXAccount *account = dynamic_cast<IAXAccount *>(Manager::instance().getAccount (_accountID));
std::string username(account->getUsername());
std::string strNum(username + ":" + account->getPassword() + "@" + account->getHostname() + "/" + call->getPeerNumber());
wait = 0;
/** @todo Make preference dynamic, and configurable */
audio_format_preferred = call->getFirstMatchingFormat (call->getSupportedFormat (_accountID), _accountID);
audio_format_capability = call->getSupportedFormat (_accountID);
int audio_format_preferred = call->getFirstMatchingFormat (call->getSupportedFormat (_accountID), _accountID);
int audio_format_capability = call->getSupportedFormat (_accountID);
_debug ("IAX New call: %s", strNum.c_str());
iax_call (newsession, username.c_str(), username.c_str(), strNum.c_str(), lang, wait, audio_format_preferred, audio_format_capability);
iax_call(newsession, username.c_str(), username.c_str(), strNum.c_str(),
NULL, 0, audio_format_preferred, audio_format_capability);
return true;
}
......@@ -740,22 +737,20 @@ IAXVoIPLink::iaxHandleCallEvent (iax_event* event, IAXCall* call)
void
IAXVoIPLink::iaxHandleVoiceEvent (iax_event* event, IAXCall* call)
{
if (!event->datalen) {
// Skip this empty packet.
//_debug("IAX: Skipping empty jitter-buffer interpolated packet");
// Skip this empty packet.
if (!event->datalen)
return;
}
if (audiolayer) {
_debug ("IAX: incoming audio, but no sound card open");
return;
}
sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(call->getAudioCodecFactory().getCodec (call->getAudioCodec()));
sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(call->getAudioCodecFactory().getCodec(call->getAudioCodec()));
if (!audioCodec)
return;
Manager::instance().getMainBuffer ()->setInternalSamplingRate (audioCodec->getClockRate ());
Manager::instance().getMainBuffer()->setInternalSamplingRate(audioCodec->getClockRate());
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
// On-the-fly codec changing (normally, when we receive a full packet)
......@@ -785,9 +780,8 @@ IAXVoIPLink::iaxHandleVoiceEvent (iax_event* event, IAXCall* call)
outSize = (double)outSize * (mainBufferSampleRate / audioRate);
converter->resample (decData, resampledData, mainBufferSampleRate, audioRate, samples);
audiolayer->getMainBuffer()->putData (resampledData, outSize, call->getCallId());
} else {
} else
audiolayer->getMainBuffer()->putData (decData, outSize, call->getCallId());
}
}
/**
......@@ -796,11 +790,7 @@ IAXVoIPLink::iaxHandleVoiceEvent (iax_event* event, IAXCall* call)
void
IAXVoIPLink::iaxHandleRegReply (iax_event* event)
{
std::string account_id;
IAXAccount *account;
account = dynamic_cast<IAXAccount *> (Manager::instance().getAccount (_accountID));
IAXAccount *account = dynamic_cast<IAXAccount *> (Manager::instance().getAccount (_accountID));
if (event->etype == IAX_EVENT_REGREJ) {
/* Authentication failed! */
......@@ -816,14 +806,6 @@ IAXVoIPLink::iaxHandleRegReply (iax_event* event)
/* Authentication succeeded */
_mutexIAX.enterMutex();
// Looking for the voicemail information
//if( event->ies != 0 )
//new_voicemails = processIAXMsgCount(event->ies.msgcount);
//_debug("iax voicemail number notification: %i", new_voicemails);
// Notify the client if new voicemail waiting for the current account
//account_id = getstd::string();
//Manager::instance().startVoiceMessageNotification(account_id.c_str(), new_voicemails);
iax_destroy (_regSession);
_mutexIAX.leaveMutex();
_regSession = NULL;
......@@ -968,8 +950,3 @@ void IAXVoIPLink::updateAudiolayer (void)
audiolayer = Manager::instance().getAudioDriver();
_mutexIAX.leaveMutex();
}
IAXAccount* IAXVoIPLink::getAccountPtr (void)
{
return dynamic_cast<IAXAccount *> (Manager::instance().getAccount (_accountID));
}
......@@ -34,14 +34,14 @@
#include "voiplink.h"
#include <iax-client.h>
#include "audio/codecs/audiocodec.h" // for DEC_BUFFER_SIZE
#include "global.h"
#include "audio/codecs/audiocodecfactory.h"
#include "audio/samplerateconverter.h"
#include "hooks/urlhook.h"
#include "im/InstantMessaging.h"
namespace sfl {
class InstantMessaging;
}
class SamplerateConverter;
class EventThread;
class IAXCall;
......@@ -191,7 +191,7 @@ class IAXVoIPLink : public VoIPLink
* Return the codec protocol used for this call
* @param id The call identifier
*/
virtual std::string getCurrentCodecName(Call *c);
virtual std::string getCurrentCodecName(Call *c) const;
public: // iaxvoiplink only
......@@ -199,9 +199,6 @@ class IAXVoIPLink : public VoIPLink
void updateAudiolayer (void);
private:
IAXAccount* getAccountPtr (void);
/*
* Decode the message count IAX send.
* Returns only the new messages number
......
......@@ -40,6 +40,7 @@
#include "dbus/callmanager.h"
#include "global.h"
#include "sip/sipaccount.h"
#include "im/InstantMessaging.h"
#include "iax/iaxaccount.h"
#include "numbercleaner.h"
......@@ -822,74 +823,52 @@ void ManagerImpl::holdConference (const std::string& id)
void ManagerImpl::unHoldConference (const std::string& id)
{
_debug ("Manager: Unhold conference()");
Conference *conf;
ConferenceMap::iterator iter_conf = _conferencemap.find (id);
bool isRec = false;
std::string currentAccountId;
Call* call = NULL;
if (iter_conf != _conferencemap.end()) {
conf = iter_conf->second;
ParticipantSet participants = conf->getParticipantList();
ParticipantSet::iterator iter_participant = participants.begin();
bool isRec = false;
if((conf->getState() == Conference::ACTIVE_ATTACHED_REC) ||
(conf->getState() == Conference::ACTIVE_DETACHED_REC) ||
(conf->getState() == Conference::HOLD_REC)) {
isRec = true;
}
Conference *conf = iter_conf->second;
while (iter_participant != participants.end()) {
_debug (" unholdConference: participant %s", (*iter_participant).c_str());
currentAccountId = getAccountFromCall (*iter_participant);
call = getAccountLink (currentAccountId)->getCall (*iter_participant);
if (conf->getState() == Conference::ACTIVE_ATTACHED_REC or
conf->getState() == Conference::ACTIVE_DETACHED_REC or
conf->getState() == Conference::HOLD_REC)
isRec = true;
// if one call is currently recording, the conference is in state recording
if(call->isRecording()) {
isRec = true;
}
ParticipantSet participants(conf->getParticipantList());
offHoldCall (*iter_participant);
for (ParticipantSet::const_iterator iter = participants.begin(); iter!= participants.end(); ++iter) {
_debug (" unholdConference: participant %s", (*iter).c_str());
std::string currentAccountId(getAccountFromCall(*iter));
Call *call = getAccountLink(currentAccountId)->getCall(*iter);
iter_participant++;
// if one call is currently recording, the conference is in state recording
isRec |= call->isRecording();
offHoldCall (*iter);
}
conf->setState (isRec ? Conference::ACTIVE_ATTACHED_REC : Conference::ACTIVE_ATTACHED);
conf->setState(isRec ? Conference::ACTIVE_ATTACHED_REC : Conference::ACTIVE_ATTACHED);
_dbus.getCallManager()->conferenceChanged (conf->getConfID(), conf->getStateStr());
}
}
bool ManagerImpl::isConference (const std::string& id)
{
ConferenceMap::iterator iter = _conferencemap.find (id);
if (iter == _conferencemap.end()) {
return false;
} else {
return true;
}
return (_conferencemap.find(id) != _conferencemap.end());
}
bool ManagerImpl::participToConference (const std::string& call_id)
{
std::string accountId = getAccountFromCall (call_id);
Call *call = getAccountLink (accountId)->getCall (call_id);
std::string accountId(getAccountFromCall(call_id));
Call *call = getAccountLink (accountId)->getCall(call_id);
if (call == NULL) {
_error("Manager: Error call is NULL in particip to conference");
return false;
}
if (call->getConfId() == "") {
if (call->getConfId().empty())
return false;
}
return true;
}
......@@ -897,30 +876,28 @@ bool ManagerImpl::participToConference (const std::string& call_id)
void ManagerImpl::addParticipant (const std::string& callId, const std::string& conferenceId)
{
_debug ("Manager: Add participant %s to %s", callId.c_str(), conferenceId.c_str());
ConferenceMap::iterator iter = _conferencemap.find (conferenceId);
if (iter == _conferencemap.end()) {
_error("Manager: Error: Conference id is not valid");
return;
}
std::string currentAccountId = getAccountFromCall (callId);
std::string currentAccountId(getAccountFromCall (callId));
Call *call = getAccountLink (currentAccountId)->getCall (callId);
if(call == NULL) {
if (call == NULL) {
_error("Manager: Error: Call id is not valid");
return;
}
// store the current call id (it will change in offHoldCall or in answerCall)
std::string current_call_id = getCurrentCallId();
std::string current_call_id(getCurrentCallId());
// detach from prior communication and switch to this conference
if (current_call_id != callId) {
if (isConference (current_call_id)) {
if (isConference (current_call_id))
detachParticipant (Call::DEFAULT_ID, current_call_id);
} else {
else
onHoldCall (current_call_id);
}
}
// TODO: remove this ugly hack => There should be different calls when double clicking
// a conference to add main participant to it, or (in this case) adding a participant
......@@ -952,18 +929,15 @@ void ManagerImpl::addParticipant (const std::string& callId, const std::string&
conf->bindParticipant (callId);
}
ParticipantSet participants = conf->getParticipantList();
if(participants.empty()) {
ParticipantSet participants(conf->getParticipantList());
if (participants.empty())
_error("Manager: Error: Participant list is empty for this conference");
}
// reset ring buffer for all conference participant
ParticipantSet::iterator iter_p = participants.begin();
while (iter_p != participants.end()) {
// flush conference participants only
getMainBuffer()->flush (*iter_p);
iter_p++;
}
// flush conference participants only
for (ParticipantSet::const_iterator iter_p = participants.begin();
iter_p != participants.end(); ++iter_p)
getMainBuffer()->flush(*iter_p);
getMainBuffer()->flush (Call::DEFAULT_ID);
......@@ -974,54 +948,41 @@ void ManagerImpl::addParticipant (const std::string& callId, const std::string&
void ManagerImpl::addMainParticipant (const std::string& conference_id)
{
if (hasCurrentCall()) {
std::string current_call_id = getCurrentCallId();
std::string current_call_id(getCurrentCallId());
if (isConference (current_call_id)) {
detachParticipant (Call::DEFAULT_ID, current_call_id);
} else {
onHoldCall (current_call_id);
}
if (isConference(current_call_id))
detachParticipant(Call::DEFAULT_ID, current_call_id);
else
onHoldCall(current_call_id);
}
ConferenceMap::iterator iter = _conferencemap.find (conference_id);
Conference *conf = NULL;
audioLayerMutexLock();
_debug("Manager: Add Main Participant");
ConferenceMap::const_iterator iter = _conferencemap.find (conference_id);
if (iter != _conferencemap.end()) {
conf = iter->second;
Conference *conf = iter->second;
ParticipantSet participants = conf->getParticipantList();
ParticipantSet::iterator iter_participant = participants.begin();
while (iter_participant != participants.end()) {
getMainBuffer()->bindCallID (*iter_participant, Call::DEFAULT_ID);
iter_participant++;
}
for (ParticipantSet::const_iterator iter_p = participants.begin();
iter_p != participants.end(); ++iter_p)
getMainBuffer()->bindCallID(*iter_p, Call::DEFAULT_ID);
// Reset ringbuffer's readpointers
iter_participant = participants.begin();
while (iter_participant != participants.end()) {
getMainBuffer()->flush (*iter_participant);
iter_participant++;
}
for (ParticipantSet::const_iterator iter_p = participants.begin();
iter_p != participants.end(); ++iter_p)
getMainBuffer()->flush(*iter_p);
getMainBuffer()->flush (Call::DEFAULT_ID);
getMainBuffer()->flush(Call::DEFAULT_ID);
if(conf->getState() == Conference::ACTIVE_DETACHED) {
conf->setState (Conference::ACTIVE_ATTACHED);
}
else if(conf->getState() == Conference::ACTIVE_DETACHED_REC) {
if (conf->getState() == Conference::ACTIVE_DETACHED)
conf->setState(Conference::ACTIVE_ATTACHED);
else if (conf->getState() == Conference::ACTIVE_DETACHED_REC)
conf->setState(Conference::ACTIVE_ATTACHED_REC);
}
else {
else
_warn("Manager: Warning: Invalid conference state while adding main participant");
}
_dbus.getCallManager()->conferenceChanged (conference_id, conf->getStateStr());
}
......@@ -1515,9 +1476,7 @@ void ManagerImpl::saveConfig (void)
//THREAD=Main
bool ManagerImpl::sendDtmf (const std::string& id, char code)
{
_debug ("Manager: Send DTMF for call %s", id.c_str());
std::string accountid = getAccountFromCall (id);
std::string accountid(getAccountFromCall(id));
playDtmf (code);
return getAccountLink (accountid)->carryingDTMFdigits (id, code);
}
......@@ -2226,8 +2185,6 @@ std::string ManagerImpl::getCurrentCodecName (const std::string& id)
Call* call = link->getCall (id);
std::string codecName;
_debug("Manager: Get current codec name");
if (call) {
Call::CallState state = call->getState();
if (state == Call::Active or state == Call::Conferencing) {
......@@ -2374,8 +2331,6 @@ std::vector<std::string> ManagerImpl::getAudioInputDeviceList (void)
*/
std::vector<std::string> ManagerImpl::getCurrentAudioDevicesIndex ()
{
_debug ("Get current audio devices index");
audioLayerMutexLock();
std::vector<std::string> v;
......@@ -2614,8 +2569,6 @@ int ManagerImpl::getAudioDeviceIndex (const std::string &name)
AlsaLayer *alsalayer;
int soundCardIndex = 0;
_debug ("Manager: Get audio device index");
audioLayerMutexLock();
if (_audiodriver == NULL) {
......@@ -2636,8 +2589,6 @@ int ManagerImpl::getAudioDeviceIndex (const std::string &name)
std::string ManagerImpl::getCurrentAudioOutputPlugin (void) const
{
_debug ("Manager: Get alsa plugin");
return audioPreference.getPlugin();
}
......@@ -3068,7 +3019,6 @@ std::vector<std::string> ManagerImpl::getAccountList () const
{
using std::vector;
using std::string;
_debug ("Manager: Get account list");
vector<string> account_order(loadAccountOrder());
// The IP2IP profile is always available, and first in the list
......@@ -3328,7 +3278,6 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser *parser)
}
}
// Initialize default UDP transport according to
// IP to IP settings (most likely using port 5060)
link->createDefaultSipUdpTransport();
......
This diff is collapsed.
......@@ -187,16 +187,6 @@ class SIPVoIPLink : public VoIPLink
*/
virtual bool carryingDTMFdigits (const std::string& id, char code);
/**
* Send Dtmf using SIP INFO message
*/
bool dtmfSipInfo (SIPCall *call, char code);
/**
* Send Dtmf over RTP
*/
void dtmfOverRtp (SIPCall* call, char code);
/**
* Start a SIP Call
* @param call The current call
......@@ -249,7 +239,7 @@ class SIPVoIPLink : public VoIPLink
* Return the codec protocol used for this call
* @param c The call identifier
*/
std::string getCurrentCodecName(Call *c);
std::string getCurrentCodecName(Call *c) const;
/**
* Retrive useragent name from account
......@@ -264,7 +254,7 @@ class SIPVoIPLink : public VoIPLink
* of IPV4 address available on all of the interfaces on
* the system.
*/
std::vector<std::string> getAllIpInterface (void);
std::vector<std::string> getAllIpInterface (void) const;
/**
* List all the interfaces on the system and return
......@@ -274,7 +264,7 @@ class SIPVoIPLink : public VoIPLink
* of interface name available on all of the interfaces on
* the system.
*/
std::vector<std::string> getAllIpInterfaceByName (void);
std::vector<std::string> getAllIpInterfaceByName (void) const;
/**
* List all the interfaces on the system and return
......@@ -284,7 +274,7 @@ class SIPVoIPLink : public VoIPLink
* of interface name available on all of the interfaces on
* the system.
*/
std::string getInterfaceAddrFromName (std::string ifaceName);
std::string getInterfaceAddrFromName (const std::string &ifaceName) const;
/**
* Initialize the transport selector
......@@ -294,11 +284,6 @@ class SIPVoIPLink : public VoIPLink
*/
pjsip_tpselector *initTransportSelector (pjsip_transport *, pj_pool_t *);
/**
* Requests PJSIP library for local IP address, using pj_gethostbyname()
*/
std::string loadSIPLocalIP ();
/**
* Helper function for creating a route set from information
* stored in configuration file.
......@@ -325,16 +310,6 @@ class SIPVoIPLink : public VoIPLink
*/
bool sendTextMessage (sfl::InstantMessaging *module, const std::string& callID, const std::string& message, const std::string& from);
/**
* Retrieve display name from the
*/
static std::string parseDisplayName(char *);
/**
* Remove the "sip:" or "sips:" from input uri
*/
static void stripSipUriPrefix(std::string&);
/**
* when we init the listener, how many times we try to bind a port?
*/
......@@ -343,8 +318,7 @@ class SIPVoIPLink : public VoIPLink
/**
* Create the default UDP transport according ot Ip2Ip profile settings
*/
bool createDefaultSipUdpTransport();
void createDefaultSipUdpTransport();
/**
* Create the default TLS litener using IP2IP_PROFILE settings
......@@ -352,6 +326,11 @@ class SIPVoIPLink : public VoIPLink
void createDefaultSipTlsListener();
private:
/**
* Send Dtmf using SIP INFO message
*/
void dtmfSipInfo (SIPCall *call, char code);
void dtmfOverRtp (SIPCall *call, char code);
/* Assignment Operator */
SIPVoIPLink& operator= (const SIPVoIPLink& rh);
......@@ -399,7 +378,6 @@ class SIPVoIPLink : public VoIPLink
*/
void createTlsListener (SIPAccount*);
/**
* General Sip transport creation method according to the
* transport type specified in account settings
......
......@@ -182,7 +182,7 @@ class VoIPLink
* Return the codec protocol used for this call
* @param call The call
*/
virtual std::string getCurrentCodecName(Call *call) = 0;
virtual std::string getCurrentCodecName(Call *call) const = 0;
/**
* Send a message to a call identified by its callid
......
Supports Markdown
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