Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
54dd1aec
Commit
54dd1aec
authored
Jan 27, 2009
by
Emmanuel Milou
Browse files
Use c++ thread in SIP, move everything in sipvoiplink;
Seems to fix or reduce deadlocks
parent
35641ddb
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
src/Makefile.am
View file @
54dd1aec
...
...
@@ -39,8 +39,7 @@ sflphoned_SOURCES = \
call.cpp
\
account.cpp
\
sipcall.cpp
\
$(IAXSOURCES)
\
useragent.cpp
$(IAXSOURCES)
sflphoned_CXXFLAGS
=
\
-DPREFIX
=
\"
$(prefix)
\"
-DPROGSHAREDIR
=
\"
${datadir}
/sflphone
\"
\
...
...
@@ -80,8 +79,7 @@ noinst_HEADERS = \
accountcreator.h
\
sipvoiplink.h
\
call.h
\
sipcall.h
\
useragent.h
sipcall.h
libsflphone_la_LIBADD
=
\
$(src)
/libs/stund/libstun.la
\
...
...
src/eventthread.cpp
View file @
54dd1aec
/*
* Copyright (C) 2004, 2005, 2006 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author : Laurielle Lea <laurielle.lea@savoirfairelinux.com>
*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
...
...
@@ -21,43 +20,31 @@
#include
"eventthread.h"
#include
"voiplink.h"
EventThread
::
EventThread
(
VoIPLink
*
link
)
:
Thread
(),
_linkthread
(
link
),
stopIt
(
false
)
{
setCancel
(
cancelDeferred
);
}
EventThread
::~
EventThread
(
void
)
{
terminate
();
}
/********************************** IAX Voiplink thread *************************************/
/**
* Reimplementation of run()
*/
void
EventThread
::
run
(
void
)
void
IAXEventThread
::
run
(
void
)
{
//stopIt = false;
while
(
!
testCancel
())
{
_linkthread
->
getEvent
();
}
}
}
void
EventThread
::
stop
(
void
)
{
stopIt
=
true
;
}
/********************************************************************************************/
void
EventThread
::
startLoop
(
void
)
{
stopIt
=
false
;
//start();
}
bool
EventThread
::
isStopped
(
void
)
/********************************** SIP Voiplink thread *************************************/
/**
* Reimplementation of run()
*/
void
SIPEventThread
::
run
(
void
)
{
return
stopIt
;
while
(
!
testCancel
())
{
_linkthread
->
getEvent
();
}
}
/********************************************************************************************/
src/eventthread.h
View file @
54dd1aec
/*
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author : Laurielle Lea <laurielle.lea@savoirfairelinux.com>
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -31,24 +30,52 @@ class VoIPLink;
*/
class
EventThread
:
public
ost
::
Thread
{
public:
/**
* Build a thread that call getEvents
*/
EventThread
(
VoIPLink
*
);
~
EventThread
(
void
);
virtual
void
run
();
virtual
void
stop
();
virtual
void
startLoop
();
bool
isStopped
();
private:
friend
class
SIPEventThread
;
friend
class
IAXEventThread
;
public:
/**
* Thread constructor
*/
EventThread
(
VoIPLink
*
link
)
:
Thread
(),
_linkthread
(
link
){
setCancel
(
cancelDeferred
);
}
virtual
~
EventThread
(
void
){
terminate
();
}
virtual
void
run
()
=
0
;
private:
EventThread
(
const
EventThread
&
rh
);
// copy constructor
EventThread
&
operator
=
(
const
EventThread
&
rh
);
// assignment operator
/** VoIPLink is the object being called by getEvents() method */
VoIPLink
*
_linkthread
;
bool
stopIt
;
VoIPLink
*
_linkthread
;
};
class
IAXEventThread
:
public
EventThread
{
public:
IAXEventThread
(
VoIPLink
*
voiplink
)
:
EventThread
(
voiplink
){
}
virtual
void
run
();
};
class
SIPEventThread
:
public
EventThread
{
public:
SIPEventThread
(
VoIPLink
*
voiplink
)
:
EventThread
(
voiplink
){
}
virtual
void
run
();
};
#endif // __EVENT_THREAD_H__
src/iaxvoiplink.cpp
View file @
54dd1aec
...
...
@@ -45,7 +45,7 @@
IAXVoIPLink
::
IAXVoIPLink
(
const
AccountID
&
accountID
)
:
VoIPLink
(
accountID
)
{
_evThread
=
new
EventThread
(
this
);
_evThread
=
new
IAX
EventThread
(
this
);
_regSession
=
NULL
;
_nextRefreshStamp
=
0
;
...
...
@@ -917,6 +917,8 @@ IAXVoIPLink::iaxCodecMapToFormat(IAXCall* call)
void
IAXVoIPLink
::
updateAudiolayer
(
void
)
{
_mutexIAX
.
enterMutex
();
audiolayer
=
NULL
;
audiolayer
=
Manager
::
instance
().
getAudioDriver
();
_mutexIAX
.
leaveMutex
();
}
src/managerimpl.cpp
View file @
54dd1aec
...
...
@@ -46,15 +46,8 @@
#include
"accountcreator.h"
// create new account
#include
"sipvoiplink.h"
#include
"useragent.h"
#include
"user_cfg.h"
#ifdef USE_ZEROCONF
#include
"zeroconf/DNSService.h"
#include
"zeroconf/DNSServiceTXTRecord.h"
#endif
#define fill_config_str(name, value) \
(_config.addConfigTreeItem(section, Conf::ConfigTreeItem(std::string(name), std::string(value), type_str)))
#define fill_config_int(name, value) \
...
...
@@ -88,26 +81,10 @@ ManagerImpl::ManagerImpl (void)
,
_callAccountMap
()
//, _callAccountMapMutex()
,
_accountMap
()
,
_userAgent
(
NULL
)
,
_userAgentInitlized
(
false
)
,
_sipThreadStop
()
{
/* Init private variables
setup: _path, _exist, _setupLoaded , _dbus
sound: _audiodriver, _dtmfKey,
_spkr_volume,_mic_volume = 0; // Initialize after by init() -> initVolume()
Call: _nbIncomingWaitingCall, _hasTriedToRegister
SIP Link: _userAgent, _userAgentInitlized
*/
#ifdef USE_ZEROCONF
_hasZeroconf
=
true
;
_DNSService
=
new
DNSService
();
#endif
// initialize random generator for call id
srand
(
time
(
NULL
));
// initialize random generator for call id
srand
(
time
(
NULL
));
#ifdef TEST
testAccountMap
();
...
...
@@ -123,82 +100,60 @@ ManagerImpl::ManagerImpl (void)
// never call if we use only the singleton...
ManagerImpl
::~
ManagerImpl
(
void
)
{
terminate
();
#ifdef USE_ZEROCONF
delete
_DNSService
;
_DNSService
=
0
;
#endif
_debug
(
"%s stop correctly.
\n
"
,
PROGNAME
);
terminate
();
_debug
(
"%s stop correctly.
\n
"
,
PROGNAME
);
}
void
ManagerImpl
::
init
()
{
// Load accounts, init map
loadAccountMap
();
// Load accounts, init map
loadAccountMap
();
//Initialize sip manager
if
(
_userAgentInitlized
)
{
_userAgent
->
sipCreate
();
_userAgent
->
sipInit
();
}
initVolume
();
initVolume
();
if
(
_exist
==
0
)
{
_debug
(
"Cannot create config file in your home directory
\n
"
);
}
initAudioDriver
();
selectAudioDriver
();
if
(
_exist
==
0
)
{
_debug
(
"Cannot create config file in your home directory
\n
"
);
}
// Initialize the list of supported audio codecs
initAudioCodec
();
initAudioDriver
();
selectAudioDriver
();
getAudioInputDeviceList
();
// Initialize the list of supported audio codecs
initAudioCodec
();
AudioLayer
*
audiolayer
=
getAudioDriver
();
if
(
audiolayer
!=
0
)
{
unsigned
int
sampleRate
=
audiolayer
->
getSampleRate
();
getAudioInputDeviceList
();
_debugInit
(
"Load Telephone Tone"
);
std
::
string
country
=
getConfigString
(
PREFERENCES
,
ZONE_TONE
);
_telephoneTone
=
new
TelephoneTone
(
country
,
s
ampleRate
);
AudioLayer
*
audiolayer
=
getAudioDriver
(
);
if
(
audiolayer
!=
0
)
{
unsigned
int
sampleRate
=
audiolayer
->
getS
ampleRate
(
);
_debugInit
(
"Load
ing DTMF key
"
);
_dtmfKey
=
new
DTMF
(
sampleRate
);
}
_debugInit
(
"Load
Telephone Tone
"
);
std
::
string
country
=
getConfigString
(
PREFERENCES
,
ZONE_TONE
);
_telephoneTone
=
new
TelephoneTone
(
country
,
sampleRate
);
// initRegisterAccounts was here, but we doing it after the gui loaded...
// the stun detection is long, so it's a better idea to do it after getEvents
initZeroconf
();
_debugInit
(
"Loading DTMF key"
);
_dtmfKey
=
new
DTMF
(
sampleRate
);
}
}
void
ManagerImpl
::
terminate
()
{
saveConfig
();
saveConfig
();
unloadAccountMap
();
unloadAccountMap
();
if
(
_userAgentInitlized
)
{
delete
_userAgent
;
_userAgent
=
NULL
;
_userAgentInitlized
=
false
;
}
_debug
(
"Unload DTMF Key
\n
"
);
delete
_dtmfKey
;
_debug
(
"Unload
DTMF Key
\n
"
);
delete
_
dtmfKey
;
_debug
(
"Unload
Audio Driver
\n
"
);
delete
_
audiodriver
;
_audiodriver
=
NULL
;
_debug
(
"Unload
Audio Driver
\n
"
);
delete
_
audiodriver
;
_audiodriver
=
NULL
;
_debug
(
"Unload
Telephone Tone
\n
"
);
delete
_
telephoneTone
;
_telephoneTone
=
NULL
;
_debug
(
"Unload Telephone Tone
\n
"
);
delete
_telephoneTone
;
_telephoneTone
=
NULL
;
_debug
(
"Unload Audio Codecs
\n
"
);
_codecDescriptorMap
.
deleteHandlePointer
();
_debug
(
"Unload Audio Codecs
\n
"
);
_codecDescriptorMap
.
deleteHandlePointer
();
}
bool
...
...
@@ -443,25 +398,29 @@ ManagerImpl::saveConfig (void)
int
ManagerImpl
::
initRegisterAccounts
()
{
int
status
;
//TODO What the flag is for ??
bool
flag
=
true
;
AccountMap
::
iterator
iter
;
_debugInit
(
"Initiate VoIP Links Registration"
);
iter
=
_accountMap
.
begin
();
/* Loop on the account map previously loaded */
while
(
iter
!=
_accountMap
.
end
()
)
{
if
(
iter
->
second
)
{
iter
->
second
->
loadConfig
();
if
(
iter
->
second
->
isEnabled
()
)
{
status
=
iter
->
second
->
registerVoIPLink
();
if
(
status
!=
SUCCESS
)
flag
=
false
;
if
(
iter
->
second
)
{
iter
->
second
->
loadConfig
();
/* If the account is set as enabled, try to register */
if
(
iter
->
second
->
isEnabled
()
)
{
status
=
iter
->
second
->
registerVoIPLink
();
if
(
status
!=
SUCCESS
){
flag
=
false
;
}
}
}
}
iter
++
;
iter
++
;
}
// calls the client notification here in case of errors at startup...
if
(
_audiodriver
->
getErrorMessage
()
!=
-
1
)
notifyErrClient
(
_audiodriver
->
getErrorMessage
()
);
...
...
@@ -1694,24 +1653,6 @@ ManagerImpl::switchAudioManager( void )
notifyErrClient
(
_audiodriver
->
getErrorMessage
());
}
/**
* Initialize the Zeroconf scanning services loop
* Informations will be store inside a map DNSService->_services
* Initialization: Main Thread
*/
void
ManagerImpl
::
initZeroconf
(
void
)
{
#ifdef USE_ZEROCONF
_debugInit
(
"Zeroconf Initialization"
);
int
useZeroconf
=
getConfigInt
(
PREFERENCES
,
CONFIG_ZEROCONF
);
if
(
useZeroconf
)
{
_DNSService
->
startScanServices
();
}
#endif
}
/**
* Init the volume for speakers/micro from 0 to 100 value
* Initialization: Main Thread
...
...
@@ -1750,6 +1691,16 @@ void ManagerImpl::setMicVolume(unsigned short mic_vol)
//}
}
void
ManagerImpl
::
setSipPort
(
int
port
)
{
}
int
ManagerImpl
::
getSipPort
(
void
)
{
return
5060
;
}
/**
* configuration function requests
* Main Thread
...
...
@@ -2021,26 +1972,17 @@ void ManagerImpl::setAccountDetails( const std::string& accountID, const std::ma
if
(
accountType
==
"SIP"
)
{
setConfig
(
accountID
,
SIP_STUN_SERVER
,(
*
details
.
find
(
SIP_STUN_SERVER
)).
second
);
setConfig
(
accountID
,
SIP_USE_STUN
,
(
*
details
.
find
(
SIP_USE_STUN
)).
second
==
"TRUE"
?
"1"
:
"0"
);
if
(
!
_userAgentInitlized
)
{
_userAgentInitlized
=
true
;
if
((
*
details
.
find
(
SIP_USE_STUN
)).
second
==
"TRUE"
)
_userAgent
->
setStunServer
((
*
details
.
find
(
SIP_STUN_SERVER
)).
second
.
data
());
else
_userAgent
->
setStunServer
(
NULL
);
_userAgent
->
sipCreate
();
_userAgent
->
sipInit
();
}
else
{
if
((
*
details
.
find
(
SIP_USE_STUN
)).
second
==
"TRUE"
)
_userAgent
->
setStunServer
((
*
details
.
find
(
SIP_STUN_SERVER
)).
second
.
data
());
else
_userAgent
->
setStunServer
(
NULL
);
restartPjsip
();
}
}
if
((
*
details
.
find
(
SIP_USE_STUN
)).
second
==
"TRUE"
)
{
//TODO Replace: _userAgent->setStunServer((*details.find(SIP_STUN_SERVER)).second.data());
}
else
{
//TODO: replace: _userAgent->setStunServer(NULL);
}
//restartPjsip();
}
saveConfig
();
...
...
@@ -2082,38 +2024,30 @@ ManagerImpl::sendRegister( const std::string& accountID , const int32_t& expire
ManagerImpl
::
addAccount
(
const
std
::
map
<
std
::
string
,
std
::
string
>&
details
)
{
/** @todo Deal with both the _accountMap and the Configuration */
std
::
string
accountType
=
(
*
details
.
find
(
CONFIG_ACCOUNT_TYPE
)).
second
;
Account
*
newAccount
;
std
::
stringstream
accountID
;
accountID
<<
"Account:"
<<
time
(
NULL
);
AccountID
newAccountID
=
accountID
.
str
();
/** @todo Verify the uniqueness, in case a program adds accounts, two in a row. */
/** @todo Deal with both the _accountMap and the Configuration */
std
::
string
accountType
=
(
*
details
.
find
(
CONFIG_ACCOUNT_TYPE
)).
second
;
Account
*
newAccount
;
std
::
stringstream
accountID
;
accountID
<<
"Account:"
<<
time
(
NULL
);
AccountID
newAccountID
=
accountID
.
str
();
/** @todo Verify the uniqueness, in case a program adds accounts, two in a row. */
if
(
accountType
==
"SIP"
)
{
if
(
!
_userAgentInitlized
)
{
// Initialize the SIP Manager
_userAgent
=
new
UserAgent
();
_userAgent
->
setSipPort
(
Manager
::
instance
().
getConfigInt
(
PREFERENCES
,
CONFIG_SIP_PORT
));
}
newAccount
=
AccountCreator
::
createAccount
(
AccountCreator
::
SIP_ACCOUNT
,
newAccountID
);
}
else
if
(
accountType
==
"IAX"
)
{
newAccount
=
AccountCreator
::
createAccount
(
AccountCreator
::
IAX_ACCOUNT
,
newAccountID
);
}
else
{
_debug
(
"Unknown %s param when calling addAccount(): %s
\n
"
,
CONFIG_ACCOUNT_TYPE
,
accountType
.
c_str
());
return
;
}
_accountMap
[
newAccountID
]
=
newAccount
;
setAccountDetails
(
accountID
.
str
(),
details
);
saveConfig
();
if
(
accountType
==
"SIP"
)
{
newAccount
=
AccountCreator
::
createAccount
(
AccountCreator
::
SIP_ACCOUNT
,
newAccountID
);
}
else
if
(
accountType
==
"IAX"
)
{
newAccount
=
AccountCreator
::
createAccount
(
AccountCreator
::
IAX_ACCOUNT
,
newAccountID
);
}
else
{
_debug
(
"Unknown %s param when calling addAccount(): %s
\n
"
,
CONFIG_ACCOUNT_TYPE
,
accountType
.
c_str
());
return
;
}
_accountMap
[
newAccountID
]
=
newAccount
;
setAccountDetails
(
accountID
.
str
(),
details
);
if
(
_dbus
)
_dbus
->
getConfigurationManager
()
->
accountsChanged
();
saveConfig
();
//restartPjsip
();
if
(
_dbus
)
_dbus
->
getConfigurationManager
()
->
accountsChanged
();
}
void
...
...
@@ -2192,20 +2126,6 @@ ManagerImpl::getNewCallID()
return
random_id
.
str
();
}
void
ManagerImpl
::
restartPjsip
()
{
if
(
_userAgentInitlized
){
unregisterCurSIPAccounts
();
_userAgent
->
sipDestory
();
//_userAgent->setSipPort(Manager::instance().getConfigInt(PREFERENCES , CONFIG_SIP_PORT));
_userAgent
->
sipCreate
();
_userAgent
->
sipInit
();
registerCurSIPAccounts
();
}
}
short
ManagerImpl
::
loadAccountMap
()
{
...
...
@@ -2214,7 +2134,6 @@ ManagerImpl::loadAccountMap()
TokenList
sections
=
_config
.
getSections
();
std
::
string
accountType
;
Account
*
tmpAccount
;
std
::
string
port
;
TokenList
::
iterator
iter
=
sections
.
begin
();
while
(
iter
!=
sections
.
end
())
{
...
...
@@ -2226,28 +2145,7 @@ ManagerImpl::loadAccountMap()
accountType
=
getConfigString
(
*
iter
,
CONFIG_ACCOUNT_TYPE
);
if
(
accountType
==
"SIP"
)
{
if
(
!
_userAgentInitlized
)
{
// Initialize the SIP Manager
_userAgent
=
new
UserAgent
();
_userAgentInitlized
=
true
;
_userAgent
->
setSipPort
(
Manager
::
instance
().
getConfigInt
(
PREFERENCES
,
CONFIG_SIP_PORT
));
}
tmpAccount
=
AccountCreator
::
createAccount
(
AccountCreator
::
SIP_ACCOUNT
,
*
iter
);
// Determine whether to use stun for the current account or not
int
useStun
=
Manager
::
instance
().
getConfigInt
(
tmpAccount
->
getAccountID
(),
SIP_USE_STUN
);
if
(
useStun
==
1
)
{
_userAgent
->
setStunServer
(
Manager
::
instance
().
getConfigString
(
tmpAccount
->
getAccountID
(),
SIP_STUN_SERVER
).
data
());
}
/*// Set registration port for all accounts, The last non-5060 port will be recorded in _userAgent.
port = Manager::instance().getConfigString(tmpAccount->getAccountID(), SIP_PORT);
std::istringstream is(port);
is >> iPort;
if (iPort != DEFAULT_SIP_PORT)
_userAgent->setRegPort(iPort); */
}
else
if
(
accountType
==
"IAX"
)
{
tmpAccount
=
AccountCreator
::
createAccount
(
AccountCreator
::
IAX_ACCOUNT
,
*
iter
);
...
...
@@ -2262,8 +2160,6 @@ ManagerImpl::loadAccountMap()
nbAccount
++
;
}
_debug
(
"
\n
"
);
iter
++
;
}
...
...
@@ -2351,37 +2247,6 @@ pjsip_regc
return
NULL
;
}
/**
* Return the instance of sip manager
*/
UserAgent
*
ManagerImpl
::
getUserAgent
()
{
return
_userAgent
;
}
int
ManagerImpl
::
getSipPort
()
{
if
(
_userAgent
)
return
_userAgent
->
getSipPort
();
else
{
// It means that no SIP accounts are configured, so return a default value
return
0
;
}
}
void
ManagerImpl
::
setSipPort
(
int
portNum
)
{
if
(
portNum
!=
_userAgent
->
getSipPort
())
{
_userAgent
->
setSipPort
(
portNum
);
restartPjsip
();
setConfig
(
PREFERENCES
,
CONFIG_SIP_PORT
,
portNum
);
}
}
void
ManagerImpl
::
unregisterCurSIPAccounts
()
{
AccountMap
::
iterator
iter
=
_accountMap
.
begin
();
...
...
src/managerimpl.h
View file @
54dd1aec
...
...
@@ -47,7 +47,6 @@ class CodecDescriptor;
class
GuiFramework
;
class
TelephoneTone
;
class
VoIPLink
;
class
UserAgent
;
#ifdef USE_ZEROCONF