Commit 1df2fa4c authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #7130: Fix segfault when detaching participant

Conference object was being deleted in processRemainingParticipants and then called.
parent a9f3dc57
......@@ -187,7 +187,7 @@ class Account : public Serializable {
* Get the voiplink pointer
* @return VoIPLink* the pointer or 0
*/
VoIPLink* getVoIPLink() const {
VoIPLink* getVoIPLink() {
return link_;
}
......
......@@ -37,45 +37,45 @@
#include "audio/mainbuffer.h"
Conference::Conference()
: _id(Manager::instance().getNewCallID())
, _confState(ACTIVE_ATTACHED)
: id_(Manager::instance().getNewCallID())
, confState_(ACTIVE_ATTACHED)
{
Recordable::initRecFileName(_id);
Recordable::initRecFileName(id_);
}
int Conference::getState() const
{
return _confState;
return confState_;
}
void Conference::setState(ConferenceState state)
{
_confState = state;
confState_ = state;
}
void Conference::add(const std::string &participant_id)
{
_participants.insert(participant_id);
participants_.insert(participant_id);
}
void Conference::remove(const std::string &participant_id)
{
_participants.erase(participant_id);
participants_.erase(participant_id);
}
void Conference::bindParticipant(const std::string &participant_id)
{
for (ParticipantSet::iterator iter = _participants.begin();
iter != _participants.end(); ++iter)
for (ParticipantSet::iterator iter = participants_.begin();
iter != participants_.end(); ++iter)
if (participant_id != *iter)
Manager::instance().getMainBuffer()->bindCallID(participant_id, *iter);
Manager::instance().getMainBuffer()->bindCallID(participant_id);
}
std::string Conference::getStateStr()
std::string Conference::getStateStr() const
{
switch (_confState) {
switch (confState_) {
case ACTIVE_ATTACHED:
return "ACTIVE_ATTACHED";
case ACTIVE_DETACHED:
......@@ -95,7 +95,7 @@ std::string Conference::getStateStr()
ParticipantSet Conference::getParticipantList() const
{
return _participants;
return participants_;
}
bool Conference::setRecording()
......@@ -105,19 +105,18 @@ bool Conference::setRecording()
Recordable::recAudio.setRecording();
MainBuffer *mbuffer = Manager::instance().getMainBuffer();
ParticipantSet::iterator iter;
std::string process_id = Recordable::recorder.getRecorderID();
std::string process_id(Recordable::recorder.getRecorderID());
// start recording
if (!recordStatus) {
for (iter = _participants.begin(); iter != _participants.end(); ++iter)
for (ParticipantSet::const_iterator iter = participants_.begin(); iter != participants_.end(); ++iter)
mbuffer->bindHalfDuplexOut(process_id, *iter);
mbuffer->bindHalfDuplexOut(process_id);
Recordable::recorder.start();
} else {
for (iter = _participants.begin(); iter != _participants.end(); ++iter)
for (ParticipantSet::const_iterator iter = participants_.begin(); iter != participants_.end(); ++iter)
mbuffer->unBindHalfDuplexOut(process_id, *iter);
mbuffer->unBindHalfDuplexOut(process_id);
......@@ -125,3 +124,12 @@ bool Conference::setRecording()
return recordStatus;
}
std::string Conference::getRecFileId() const {
return getConfID();
}
std::string Conference::getConfID() const {
return id_;
}
......@@ -49,9 +49,7 @@ class Conference: public Recordable {
/**
* Return the conference id
*/
std::string getConfID() const {
return _id;
}
std::string getConfID() const;
/**
* Return the current conference state
......@@ -66,7 +64,7 @@ class Conference: public Recordable {
/**
* Return a string description of the conference state
*/
std::string getStateStr();
std::string getStateStr() const;
/**
* Add a new participant to the conference
......@@ -91,31 +89,18 @@ class Conference: public Recordable {
/**
* Get recording file ID
*/
std::string getRecFileId() const {
return getConfID();
}
std::string getRecFileId() const;
/**
* Start/stop recording toggle
*/
virtual bool setRecording();
private:
std::string id_;
/**
* Unique ID of the conference
*/
std::string _id;
/**
* Conference state
*/
ConferenceState _confState;
ConferenceState confState_;
/**
* List of participant ids
*/
ParticipantSet _participants;
ParticipantSet participants_;
};
#endif
......@@ -29,7 +29,7 @@
*/
#include <cstdlib>
#include <dbusmanager.h>
#include "dbusmanager.h"
#include "global.h"
#include "manager.h"
#include "instance.h"
......@@ -42,43 +42,43 @@ DBusManager::DBusManager()
{
try {
DBus::_init_threading();
DBus::default_dispatcher = &_dispatcher;
DBus::default_dispatcher = &dispatcher_;
DBus::Connection sessionConnection = DBus::Connection::SessionBus();
sessionConnection.request_name("org.sflphone.SFLphone");
_callManager = new CallManager(sessionConnection);
_configurationManager = new ConfigurationManager(sessionConnection);
_instanceManager = new Instance(sessionConnection);
callManager_ = new CallManager(sessionConnection);
configurationManager_ = new ConfigurationManager(sessionConnection);
instanceManager_ = new Instance(sessionConnection);
#ifdef USE_NETWORKMANAGER
DBus::Connection systemConnection = DBus::Connection::SystemBus();
_networkManager = new NetworkManager(systemConnection, "/org/freedesktop/NetworkManager", "");
networkManager_ = new NetworkManager(systemConnection, "/org/freedesktop/NetworkManager", "");
#endif
} catch (const DBus::Error &err) {
_error("%s: %s, exiting\n", err.name(), err.what());
::exit(1);
::exit(EXIT_FAILURE);
}
}
DBusManager::~DBusManager()
{
#ifdef USE_NETWORKMANAGER
delete _networkManager;
delete networkManager_;
#endif
delete _instanceManager;
delete _configurationManager;
delete _callManager;
delete instanceManager_;
delete configurationManager_;
delete callManager_;
}
void DBusManager::exec()
{
_dispatcher.enter();
dispatcher_.enter();
}
void
DBusManager::exit()
{
_dispatcher.leave();
dispatcher_.leave();
}
......@@ -43,23 +43,23 @@ class DBusManager {
DBusManager();
~DBusManager();
CallManager * getCallManager() const {
return _callManager;
CallManager * getCallManager() {
return callManager_;
};
ConfigurationManager * getConfigurationManager() const {
return _configurationManager;
ConfigurationManager * getConfigurationManager() {
return configurationManager_;
};
void exec();
void exit();
private:
CallManager* _callManager;
ConfigurationManager* _configurationManager;
Instance* _instanceManager;
DBus::BusDispatcher _dispatcher;
CallManager* callManager_;
ConfigurationManager* configurationManager_;
Instance* instanceManager_;
DBus::BusDispatcher dispatcher_;
#if USE_NETWORKMANAGER
NetworkManager* _networkManager;
NetworkManager* networkManager_;
#endif
};
......
......@@ -67,27 +67,24 @@
#include <sys/types.h> // mkdir(2)
#include <sys/stat.h> // mkdir(2)
ManagerImpl::ManagerImpl(void) :
_hasTriedToRegister(false), _config(), currentCallId_(),
_currentCallMutex(), _audiodriver(0),
_dtmfKey(0), _toneMutex(),
_telephoneTone(0), _audiofile(0), _spkr_volume(0),
_mic_volume(0), _waitingCall(),
_waitingCallMutex(), _nbIncomingWaitingCall(0), _path(""),
_callAccountMap(),
_callAccountMapMutex(), _callConfigMap(), _accountMap(),
_history(new HistoryManager), _imModule(new sfl::InstantMessaging)
ManagerImpl::ManagerImpl() :
hasTriedToRegister_(false), config_(), currentCallId_(),
currentCallMutex_(), audiodriver_(0), dtmfKey_(0), toneMutex_(),
telephoneTone_(0), audiofile_(0), speakerVolume_(0), micVolume_(0),
waitingCall_(), waitingCallMutex_(), nbIncomingWaitingCall_(0), path_(""),
callAccountMap_(), callAccountMapMutex_(), callConfigMap_(), accountMap_(),
history_(new HistoryManager), imModule_(new sfl::InstantMessaging)
{
// initialize random generator for call id
srand(time(NULL));
}
// never call if we use only the singleton...
ManagerImpl::~ManagerImpl(void)
ManagerImpl::~ManagerImpl()
{
delete _imModule;
delete _history;
delete _audiofile;
delete imModule_;
delete history_;
delete audiofile_;
}
void ManagerImpl::init(std::string config_file)
......@@ -95,14 +92,14 @@ void ManagerImpl::init(std::string config_file)
if (config_file.empty())
config_file = getConfigFile();
_path = config_file;
path_ = config_file;
_debug("Manager: configuration file path: %s", _path.c_str());
_debug("Manager: configuration file path: %s", path_.c_str());
Conf::YamlParser *parser = NULL;
try {
parser = new Conf::YamlParser(_path.c_str());
parser = new Conf::YamlParser(path_.c_str());
parser->serializeEvents();
parser->composeEvents();
parser->constructNativeData();
......@@ -121,14 +118,14 @@ void ManagerImpl::init(std::string config_file)
audioLayerMutexLock();
if (_audiodriver) {
_telephoneTone = new TelephoneTone(preferences.getZoneToneChoice(), _audiodriver->getSampleRate());
_dtmfKey = new DTMF(8000);
if (audiodriver_) {
telephoneTone_ = new TelephoneTone(preferences.getZoneToneChoice(), audiodriver_->getSampleRate());
dtmfKey_ = new DTMF(8000);
}
audioLayerMutexUnlock();
_history->load_history(preferences.getHistoryLimit());
history_->load_history(preferences.getHistoryLimit());
registerAccounts();
}
......@@ -137,39 +134,35 @@ void ManagerImpl::terminate()
std::vector<std::string> callList(getCallList());
_debug("Manager: Hangup %zu remaining call", callList.size());
std::vector<std::string>::iterator iter;
for (iter = callList.begin(); iter != callList.end(); ++iter)
for (std::vector<std::string>::iterator iter = callList.begin(); iter != callList.end(); ++iter)
hangupCall(*iter);
unloadAccountMap();
delete SIPVoIPLink::instance();
delete _dtmfKey;
delete _telephoneTone;
_telephoneTone = NULL;
delete dtmfKey_;
delete telephoneTone_;
telephoneTone_ = NULL;
audioLayerMutexLock();
delete _audiodriver;
_audiodriver = NULL;
delete audiodriver_;
audiodriver_ = NULL;
audioLayerMutexUnlock();
}
bool ManagerImpl::isCurrentCall(const std::string& callId)
bool ManagerImpl::isCurrentCall(const std::string& callId) const
{
return currentCallId_ == callId;
}
bool ManagerImpl::hasCurrentCall()
bool ManagerImpl::hasCurrentCall() const
{
return not currentCallId_.empty();
}
const std::string&
std::string
ManagerImpl::getCurrentCallId() const
{
return currentCallId_;
......@@ -177,7 +170,7 @@ ManagerImpl::getCurrentCallId() const
void ManagerImpl::switchCall(const std::string& id)
{
ost::MutexLock m(_currentCallMutex);
ost::MutexLock m(currentCallMutex_);
_debug("----- Switch current call id to %s -----", id.c_str());
currentCallId_ = id;
}
......@@ -188,7 +181,9 @@ void ManagerImpl::switchCall(const std::string& id)
/* Main Thread */
bool ManagerImpl::outgoingCall(const std::string& account_id,
const std::string& call_id, const std::string& to, const std::string& conf_id)
const std::string& call_id,
const std::string& to,
const std::string& conf_id)
{
if (call_id.empty()) {
_debug("Manager: New outgoing call abort, missing callid");
......@@ -208,7 +203,6 @@ bool ManagerImpl::outgoingCall(const std::string& account_id,
std::string current_call_id(getCurrentCallId());
std::string prefix;
if (hookPreference.getNumberEnabled())
prefix = hookPreference.getNumberAddPrefix();
......@@ -330,9 +324,9 @@ bool ManagerImpl::answerCall(const std::string& call_id)
// update call state on client side
if (audioPreference.getIsAlwaysRecording())
_dbus.getCallManager()->callStateChanged(call_id, "RECORD");
dbus_.getCallManager()->callStateChanged(call_id, "RECORD");
else
_dbus.getCallManager()->callStateChanged(call_id, "CURRENT");
dbus_.getCallManager()->callStateChanged(call_id, "CURRENT");
return true;
}
......@@ -349,7 +343,7 @@ void ManagerImpl::hangupCall(const std::string& callId)
/* Broadcast a signal over DBus */
_debug("Manager: Send DBUS call state change (HUNGUP) for id %s", callId.c_str());
_dbus.getCallManager()->callStateChanged(callId, "HUNGUP");
dbus_.getCallManager()->callStateChanged(callId, "HUNGUP");
if (not isValidCall(callId) and not getConfigFromCall(callId) == Call::IPtoIP) {
_error("Manager: Error: Could not hang up call, call not valid");
......@@ -393,9 +387,9 @@ bool ManagerImpl::hangupConference(const std::string& id)
{
_debug("Manager: Hangup conference %s", id.c_str());
ConferenceMap::iterator iter_conf = _conferencemap.find(id);
ConferenceMap::iterator iter_conf = conferenceMap_.find(id);
if (iter_conf != _conferencemap.end()) {
if (iter_conf != conferenceMap_.end()) {
Conference *conf = iter_conf->second;
if (conf) {
......@@ -457,7 +451,7 @@ void ManagerImpl::onHoldCall(const std::string& callId)
if (current_call_id == callId)
switchCall("");
_dbus.getCallManager()->callStateChanged(callId, "HOLD");
dbus_.getCallManager()->callStateChanged(callId, "HOLD");
getMainBuffer()->stateInfo();
}
......@@ -505,7 +499,7 @@ void ManagerImpl::offHoldCall(const std::string& callId)
}
}
_dbus.getCallManager()->callStateChanged(callId, isRec ? "UNHOLD_RECORD" : "UNHOLD_CURRENT");
dbus_.getCallManager()->callStateChanged(callId, isRec ? "UNHOLD_RECORD" : "UNHOLD_CURRENT");
if (participToConference(callId)) {
std::string currentAccountId(getAccountFromCall(callId));
......@@ -527,8 +521,9 @@ bool ManagerImpl::transferCall(const std::string& callId, const std::string& to)
{
if (participToConference(callId)) {
removeParticipant(callId);
processRemainingParticipants(callId, getConferenceFromCallID(callId));
} else if (!isConference(getCurrentCallId()))
Conference *conf = getConferenceFromCallID(callId);
processRemainingParticipants(callId, conf);
} else if (not isConference(getCurrentCallId()))
switchCall("");
// Direct IP to IP call
......@@ -537,7 +532,7 @@ bool ManagerImpl::transferCall(const std::string& callId, const std::string& to)
else {
std::string accountid(getAccountFromCall(callId));
if (accountid == "")
if (accountid.empty())
return false;
getAccountLink(accountid)->transfer(callId, to);
......@@ -553,12 +548,12 @@ bool ManagerImpl::transferCall(const std::string& callId, const std::string& to)
void ManagerImpl::transferFailed()
{
_dbus.getCallManager()->transferFailed();
dbus_.getCallManager()->transferFailed();
}
void ManagerImpl::transferSucceded()
{
_dbus.getCallManager()->transferSucceded();
dbus_.getCallManager()->transferSucceded();
}
bool ManagerImpl::attendedTransfer(const std::string& transferID, const std::string& targetID)
......@@ -582,7 +577,7 @@ void ManagerImpl::refuseCall(const std::string& id)
if (getCallList().size() <= 1) {
audioLayerMutexLock();
_audiodriver->stopStream();
audiodriver_->stopStream();
audioLayerMutexUnlock();
}
......@@ -603,7 +598,7 @@ void ManagerImpl::refuseCall(const std::string& id)
}
removeWaitingCall(id);
_dbus.getCallManager()->callStateChanged(id, "HUNGUP");
dbus_.getCallManager()->callStateChanged(id, "HUNGUP");
// Disconnect streams
removeStream(id);
......@@ -623,10 +618,10 @@ ManagerImpl::createConference(const std::string& id1, const std::string& id2)
conf->add(id2);
// Add conference to map
_conferencemap.insert(ConferenceEntry(conf->getConfID(), conf));
conferenceMap_.insert(ConferenceEntry(conf->getConfID(), conf));
// broadcast a signal over dbus
_dbus.getCallManager()->conferenceCreated(conf->getConfID());
dbus_.getCallManager()->conferenceCreated(conf->getConfID());
return conf;
}
......@@ -635,12 +630,12 @@ void ManagerImpl::removeConference(const std::string& conference_id)
{
_debug("Manager: Remove conference %s", conference_id.c_str());
_debug("Manager: number of participants: %u", _conferencemap.size());
ConferenceMap::iterator iter = _conferencemap.find(conference_id);
_debug("Manager: number of participants: %u", conferenceMap_.size());
ConferenceMap::iterator iter = conferenceMap_.find(conference_id);
Conference* conf = NULL;
Conference* conf = 0;
if (iter != _conferencemap.end())
if (iter != conferenceMap_.end())
conf = iter->second;
if (conf == NULL) {
......@@ -649,7 +644,7 @@ void ManagerImpl::removeConference(const std::string& conference_id)
}
// broadcast a signal over dbus
_dbus.getCallManager()->conferenceRemoved(conference_id);
dbus_.getCallManager()->conferenceRemoved(conference_id);
// We now need to bind the audio to the remain participant
......@@ -665,7 +660,7 @@ void ManagerImpl::removeConference(const std::string& conference_id)
getMainBuffer()->bindCallID(*iter_p, Call::DEFAULT_ID);
// Then remove the conference from the conference map
if (_conferencemap.erase(conference_id) == 1)
if (conferenceMap_.erase(conference_id) == 1)
_debug("Manager: Conference %s removed successfully", conference_id.c_str());
else
_error("Manager: Error: Cannot remove conference: %s", conference_id.c_str());
......@@ -679,9 +674,9 @@ ManagerImpl::getConferenceFromCallID(const std::string& call_id)
std::string account_id(getAccountFromCall(call_id));
Call *call = getAccountLink(account_id)->getCall(call_id);
ConferenceMap::const_iterator iter = _conferencemap.find(call->getConfId());
ConferenceMap::const_iterator iter(conferenceMap_.find(call->getConfId()));
if (iter != _conferencemap.end())
if (iter != conferenceMap_.end())
return iter->second;
else
return NULL;
......@@ -689,15 +684,15 @@ ManagerImpl::getConferenceFromCallID(const std::string& call_id)
void ManagerImpl::holdConference(const std::string& id)
{
ConferenceMap::iterator iter_conf = _conferencemap.find(id);
ConferenceMap::iterator iter_conf = conferenceMap_.find(id);
if (iter_conf == _conferencemap.end())
if (iter_conf == conferenceMap_.end())
return;
Conference *conf = iter_conf->second;
bool isRec = conf->getState() == Conference::ACTIVE_ATTACHED_REC ||
conf->getState() == Conference::ACTIVE_DETACHED_REC ||
bool isRec = conf->getState() == Conference::ACTIVE_ATTACHED_REC or
conf->getState() == Conference::ACTIVE_DETACHED_REC or
conf->getState() == Conference::HOLD_REC;
ParticipantSet participants(conf->getParticipantList());
......@@ -709,14 +704,14 @@ void ManagerImpl::holdConference(const std::string& id)
}
conf->setState(isRec ? Conference::HOLD_REC : Conference::HOLD);
_dbus.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
dbus_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
}
void ManagerImpl::unHoldConference(const std::string& id)
{
ConferenceMap::iterator iter_conf = _conferencemap.find(id);
ConferenceMap::iterator iter_conf = conferenceMap_.find(id);
if (iter_conf != _conferencemap.end()) {
if (iter_conf != conferenceMap_.end() and iter_conf->second) {
Conference *conf = iter_conf->second;
bool isRec = conf->getState() == Conference::ACTIVE_ATTACHED_REC or
......@@ -735,13 +730,13 @@ void ManagerImpl::unHoldConference(const std::string& id)
}
conf->setState(isRec ? Conference::ACTIVE_ATTACHED_REC : Conference::ACTIVE_ATTACHED);
_dbus.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
dbus_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
}
}
bool ManagerImpl::isConference(const std::string& id)
{
return (_conferencemap.find(id) != _conferencemap.end());