Commit 7a39f0c6 authored by Rafaël Carré's avatar Rafaël Carré

* #6554 : simplify sipvoiplink

Now it's created before accounts
parent 8c124d57
......@@ -193,19 +193,17 @@ class Account : public Serializable
return link_;
}
virtual void setVoIPLink () = 0;
/**
* Register the underlying VoIPLink. Launch the event listener.
* This should update the getRegistrationState() return value.
*/
virtual int registerVoIPLink() = 0;
virtual void registerVoIPLink() = 0;
/**
* Unregister the underlying VoIPLink. Stop the event listener.
* This should update the getRegistrationState() return value.
*/
virtual int unregisterVoIPLink() = 0;
virtual void unregisterVoIPLink() = 0;
/**
* Tell if the account is enable or not.
......
......@@ -39,7 +39,6 @@ namespace Conf
{
YamlParser::YamlParser (const char *file) : filename (file)
, fd(NULL)
, events()
, eventNumber (0)
, doc (NULL)
......@@ -53,7 +52,6 @@ YamlParser::YamlParser (const char *file) : filename (file)
, shortcutNode (NULL)
{
fd = fopen (filename.c_str(), "rb");
if (!fd)
throw YamlParserException ("Could not open file descriptor");
......@@ -65,11 +63,7 @@ YamlParser::YamlParser (const char *file) : filename (file)
YamlParser::~YamlParser()
{
if (!fd)
throw YamlParserException ("File descriptor not valid");
if (fclose (fd))
throw YamlParserException ("Error closing file descriptor");
fclose (fd);
yaml_parser_delete (&parser);
......@@ -79,7 +73,6 @@ YamlParser::~YamlParser()
if (doc) {
doc->deleteChildNodes();
delete doc;
doc = NULL;
}
}
......
......@@ -33,7 +33,7 @@
/********************************** Voiplink thread *************************************/
EventThread::EventThread (VoIPLink *link)
: Thread(), _linkthread (link)
: Thread(), _link (link)
{
setCancel (cancelDeferred);
}
......@@ -44,9 +44,7 @@ EventThread::EventThread (VoIPLink *link)
*/
void EventThread::run (void)
{
while (!testCancel()) {
if (_linkthread)
_linkthread->getEvent();
}
while (!testCancel())
_link->getEvent();
}
......@@ -61,7 +61,7 @@ class EventThread : public ost::Thread
EventThread& operator= (const EventThread& rh); // assignment operator
/** VoIPLink is the object being called by getEvents() method */
VoIPLink* _linkthread;
VoIPLink* _link;
};
#endif // __EVENT_THREAD_H__
......@@ -29,47 +29,13 @@
*/
#include "urlhook.h"
#include <iostream>
#include <vector>
#include <cstdlib>
UrlHook::UrlHook () { }
UrlHook::~UrlHook () { }
int UrlHook::addAction (std::string field_value, std::string command)
void UrlHook::runAction (std::string command, std::string args)
{
std::string command_bg;
std::string temp;
std::vector <std::string> args;
size_t pos;
unsigned int i;
/* Escape the '&' char to not discard $_GET parameters in the URL - #2659 */
while ( (pos = field_value.find ("&", 0)) != std::string::npos) {
temp = field_value.substr (0, pos);
field_value.erase (0, pos + 1);
args.push_back (temp);
}
command_bg = command + " ";
pos = args.size ();
for (i=0; i<pos; i++) {
// Escape the "&"
command_bg += args[i] + "\\&";
}
// Retrieve the last argument
command_bg += field_value;
/* Execute the command in the background to not block the application */
command_bg += "&";
/* Execute a system call */
return RUN_COMMAND (command_bg.c_str());
//FIXME : use fork and execve, so no need to escape shell arguments
std::string cmd = command + "\"" + args + "\" &";
system(cmd.c_str());
}
......@@ -32,27 +32,11 @@
#define URL_HOOK_H
#include <string>
#include <stdlib.h>
#define RUN_COMMAND(command) system(command);
class UrlHook
{
public:
/**
* Constructor
*/
UrlHook ();
/**
* Destructor
*/
~UrlHook ();
int addAction (std::string, std::string);
private:
public:
static void runAction (std::string, std::string);
};
#endif // URL_HOOK_H
......@@ -143,38 +143,27 @@ std::map<std::string, std::string> IAXAccount::getAccountDetails() const
return a;
}
void IAXAccount::setVoIPLink()
{
}
int IAXAccount::registerVoIPLink()
void IAXAccount::registerVoIPLink()
{
try {
link_->init();
link_->sendRegister (this);
}
catch (const VoipLinkException &e) {
_error("IAXAccount: %s", e.what());
}
return 0;
}
int
void
IAXAccount::unregisterVoIPLink()
{
try {
link_->sendUnregister (this);
link_->terminate();
return 0;
}
catch (const VoipLinkException &e) {
_error("IAXAccount: %s", e.what());
}
return 0;
}
void
......
......@@ -52,8 +52,6 @@ class IAXAccount : public Account
std::map<std::string, std::string> getAccountDetails() const;
void setVoIPLink ();
/**
* Actually useless, since config loading is done in init()
*/
......@@ -62,12 +60,12 @@ class IAXAccount : public Account
/**
* Register an account
*/
int registerVoIPLink();
void registerVoIPLink();
/**
* Unregister an account
*/
int unregisterVoIPLink();
void unregisterVoIPLink();
std::string getPassword (void) const {
return password_;
......
......@@ -64,7 +64,6 @@ IAXVoIPLink::IAXVoIPLink (const std::string& accountID) : VoIPLink ()
, audiolayer (NULL)
, converter (NULL)
, converterSamplingRate (0)
, urlhook (NULL)
, _accountID(accountID)
{
_evThread = new EventThread (this);
......@@ -73,7 +72,6 @@ IAXVoIPLink::IAXVoIPLink (const std::string& accountID) : VoIPLink ()
srand (time (NULL));
converter = new SamplerateConverter (44100);
urlhook = new UrlHook ();
}
......@@ -611,17 +609,10 @@ IAXVoIPLink::iaxFindCallBySession (struct iax_session* session)
// access to callMap shoud use that
// the code below is like findSIPCallWithCid()
ost::MutexLock m (_callMapMutex);
IAXCall* call = NULL;
CallMap::iterator iter = _callMap.begin();
while (iter != _callMap.end()) {
call = dynamic_cast<IAXCall*> (iter->second);
if (call && call->getSession() == session) {
for (CallMap::iterator iter = _callMap.begin(); iter != _callMap.end(); ++iter) {
IAXCall* call = dynamic_cast<IAXCall*> (iter->second);
if (call && call->getSession() == session)
return call;
}
iter++;
}
return NULL; // not found
......@@ -740,9 +731,9 @@ IAXVoIPLink::iaxHandleCallEvent (iax_event* event, IAXCall* call)
case IAX_EVENT_URL:
if (Manager::instance().getConfigString (HOOKS, URLHOOK_IAX2_ENABLED) == "1") {
if (strcmp ( (char*) event->data, "") != 0) {
if (*event->data) {
_debug ("> IAX_EVENT_URL received: %s", event->data);
urlhook->addAction ( (char*) event->data, Manager::instance().getConfigString (HOOKS, URLHOOK_COMMAND));
UrlHook::runAction (Manager::instance().getConfigString (HOOKS, URLHOOK_COMMAND), (char*) event->data);
}
}
......
......@@ -296,8 +296,11 @@ class IAXVoIPLink : public VoIPLink
int converterSamplingRate;
/* URL hook */
UrlHook *urlhook;
/** Whether init() was called already or not
* This should be used in init() and terminate(), to
* indicate that init() was called, or reset by terminate().
*/
bool _initDone;
const std::string _accountID;
};
......
......@@ -47,8 +47,8 @@ void setDebugMode (bool);
#define _debug(...) Logger::log(LOG_DEBUG, __VA_ARGS__)
#define _debugException(...) Logger::log(LOG_DEBUG, __VA_ARGS__)
#define _debugInit(...) Logger::log(LOG_DEBUG, __VA_ARGS__)
#define _debugAlsa(...) Logger::log(LOG_DEBUG, __VA_ARGS__)
#define _debugInit(...) Logger::log(LOG_DEBUG, __VA_ARGS__)
#define _debugAlsa(...) Logger::log(LOG_DEBUG, __VA_ARGS__)
#define BLACK "\033[22;30m"
#define RED "\033[22;31m"
......
......@@ -58,123 +58,87 @@ ost::CommandOptionNoArg help (
"help", "h", "Print help"
);
// returns true if directory exists
static bool check_dir(const char *path)
{
DIR *dir = opendir (path);
if (!dir) { // doesn't exist
if (mkdir (path, 0755) != 0) { // couldn't create the dir
perror(path);
return false;
}
} else {
closedir(dir);
}
return true;
}
int
main (int argc, char **argv)
{
set_program_dir(argv[0]);
Logger::setConsoleLog (false);
Logger::setDebugMode (false);
// makeCommandOptionParse allocates the object with operator new, so
// auto_ptr is fine in this context.
// TODO: This should eventually be replaced with std::unique_ptr for C++0x
std::auto_ptr<ost::CommandOptionParse> args(ost::makeCommandOptionParse (argc, argv, ""));
printf ("SFLphone Daemon %s, by Savoir-Faire Linux 2004-2011\n", VERSION);
printf ("http://www.sflphone.org/\n");
printf ("SFLphone Daemon "VERSION", by Savoir-Faire Linux 2004-2011\n" \
"http://www.sflphone.org/\n");
if (help.numSet) {
std::cerr << args->printUsage();
return 0;
}
else if (args->argsHaveError()) {
} else if (args->argsHaveError()) {
std::cerr << args->printErrors();
std::cerr << args->printUsage();
return 1;
}
if (console.numSet)
Logger::setConsoleLog (true);
if (debug.numSet)
Logger::setDebugMode (true);
FILE *fp;
char homepid[128];
char sfldir[128];
unsigned int iPid = getpid();
char cPid[64], cOldPid[64];
snprintf (cPid, sizeof (cPid), "%d", iPid);
std::string xdg_cache, xdg_env, path;
xdg_cache = std::string (HOMEDIR) + DIR_SEPARATOR_STR + ".cache/";
if (XDG_CACHE_HOME != NULL) {
xdg_env = std::string (XDG_CACHE_HOME);
(xdg_env.length() > 0) ? path = xdg_env
: path = xdg_cache;
} else
path = xdg_cache;
// Use safe sprintf (Contribution #4952, Brendan Smith)
snprintf (sfldir, sizeof (sfldir), "%s", path.c_str ());
path = path + "sflphone";
// Use safe sprintf (Contribution #4952, Brendan Smith)
snprintf (homepid, sizeof (homepid), "%s/%s", path.c_str (), PIDFILE);
if ( (fp = fopen (homepid,"r")) == NULL) {
// Check if $XDG_CACHE_HOME directory exists or not.
DIR *dir;
if ( (dir = opendir (sfldir)) == NULL) {
//Create it
if (mkdir (sfldir, 0755) != 0) {
fprintf (stderr, "Creating directory %s failed. Exited.", sfldir);
return 1;
}
}
// Then create the sflphone directory inside the $XDG_CACHE_HOME dir
snprintf (sfldir, sizeof (sfldir), "%s", path.c_str ());
if ( (dir = opendir (sfldir)) == NULL) {
//Create it
if (mkdir (sfldir, 0755) != 0) {
fprintf (stderr, "Creating directory %s failed. Exited.", sfldir);
return 1;
}
}
// PID file doesn't exists, create and write pid in it
if ( (fp = fopen (homepid,"w")) == NULL) {
fprintf (stderr, "Creating PID file %s failed. Exited.", homepid);
return 1;
} else {
fputs (cPid , fp);
fclose (fp);
}
Logger::setConsoleLog (console.numSet);
Logger::setDebugMode (debug.numSet);
const char *xdg_env = XDG_CACHE_HOME;
std::string path = xdg_env ? xdg_env : std::string(HOMEDIR) + DIR_SEPARATOR_STR ".cache/";
if (!check_dir(path.c_str()))
return 1;
path = path + "sflphone";
if (!check_dir(path.c_str()))
return 1;
std::string pidfile = path + "/" PIDFILE;
FILE *fp = fopen (pidfile.c_str(),"r");
if (fp) { // PID file exists. Check the former process still alive or not. If alive, give user a hint.
int oldPid;
if (fscanf(fp, "%d", &oldPid) != 1) {
fprintf(stderr, "Couldn't read pidfile %s\n", pidfile.c_str());
return 1;
}
fclose (fp);
if (kill (oldPid, 0) == 0) {
fprintf (stderr, "There is already a sflphoned daemon running in the system. Starting Failed.");
return 1;
}
}
// write pid file
fp = fopen (pidfile.c_str(),"w");
if (!fp) {
perror(pidfile.c_str());
return 1;
} else {
// PID file exists. Check the former process still alive or not. If alive, give user a hint.
char *res;
res = fgets (cOldPid, 64, fp);
if (res == NULL) perror ("Error getting string from stream");
else {
fclose (fp);
if (kill (atoi (cOldPid), 0) == 0) {
fprintf (stderr, "There is already a sflphoned daemon running in the system. Starting Failed.");
return 1;
} else {
if ( (fp = fopen (homepid,"w")) == NULL) {
fprintf (stderr, "Writing to PID file %s failed. Exited.", homepid);
return 1;
} else {
fputs (cPid , fp);
fclose (fp);
}
}
}
std::ostringstream pidstr;
pidstr << getpid();
fputs (pidstr.str().c_str() , fp);
fclose (fp);
}
try {
// TODO Use $XDG_CONFIG_HOME to save the config file (which default to $HOME/.config)
Manager::instance().initConfigFile();
Manager::instance().init();
} catch (std::exception &e) {
std::cerr << e.what() << std::endl;
......@@ -189,4 +153,3 @@ main (int argc, char **argv)
return 0;
}
This diff is collapsed.
......@@ -148,16 +148,11 @@ class ManagerImpl
*/
ShortcutPreferences shortcutPreferences;
/**
* Method to build preferences from configuration
*/
short buildConfiguration();
/**
* Initialisation of thread (sound) and map.
* Init a new VoIPLink, audio codec and audio driver
*/
void init (void);
void init (std::string config_file="");
/**
* Terminate all thread (sound, link) and unload AccountMap
......@@ -362,10 +357,8 @@ class ManagerImpl
/**
* Save config to file
* @return true on success
* false otherwise
*/
bool saveConfig (void);
void saveConfig (void);
/**
* @return true if we tried to register once
......@@ -964,22 +957,6 @@ class ManagerImpl
*/
void setMicVolume (unsigned short mic_vol);
/**
* Init default values for the different fields in the config file.
* Fills the local _config (Conf::ConfigTree) with the default contents.
* Called in main.cpp, just before Manager::init().
*/
void initConfigFile (std::string alternate="");
/**
* Tell if the setup was already loaded
* @return bool True if yes
* false otherwise
*/
bool hasLoadedSetup() {
return _setupLoaded;
}
/**
* Return a new random callid that is not present in the list
* @return std::string A brand new callid
......@@ -999,14 +976,6 @@ class ManagerImpl
*/
bool isCurrentCall (const std::string& callId);
/**
* Send registration to all enabled accounts
* @return 0 on registration success
* 1 otherelse
*/
int registerAccounts();
/*
* Initialize audiodriver
*/
......@@ -1134,8 +1103,6 @@ class ManagerImpl
*/
std::string _path;
int _setupLoaded;
#ifdef USE_ZEROCONF
// DNSService contain every zeroconf services
// configuration detected on the network
......@@ -1160,15 +1127,10 @@ class ManagerImpl
*Contains a list of account (sip, aix, etc) and their respective voiplink/calls */
AccountMap _accountMap;
Account * _directIpAccount;
void loadIptoipProfile();
/**
* Load the account from configuration
* @return short Number of account
*/
short loadAccountMap();
void loadAccountMap(Conf::YamlParser *parser);
/**
* Unload the account (delete them)
......@@ -1295,6 +1257,11 @@ class ManagerImpl
// Map containing conference pointers
ConferenceMap _conferencemap;
/**
* Send registration to all enabled accounts
*/
void registerAccounts();
private:
// Copy Constructor
......@@ -1303,13 +1270,6 @@ class ManagerImpl
// Assignment Operator
ManagerImpl& operator= (const ManagerImpl& rh);
/**
* Send registration to all enabled accounts
* @return 0 on registration success
* 1 otherelse
*/
int initRegisterAccounts();
NumberCleaner *_cleaner;
/**
......@@ -1328,7 +1288,6 @@ class ManagerImpl
*/
void checkCallConfiguration (const std::string& id, const std::string& to, Call::CallConfiguration *callConfig);
Conf::YamlParser *parser_;
Conf::YamlEmitter *emitter;
friend class SIPTest;
......
......@@ -38,115 +38,41 @@
#include "account.h"
#include "dbus/callmanager.h"
#include "global.h"
#include "sip/sipaccount.h"
#include "audio/audiolayer.h"
#include "sip/sipvoiplink.h"
#include "manager.h"
#include "dbus/configurationmanager.h"
#include "conference.h"
#include <errno.h>
#include <cstdlib>
int
void
ManagerImpl::registerAccounts()
{
int status;
bool flag = true;
AccountMap::iterator iter;
_debugInit ("Manager: Initiate VoIP Links Registration");
iter = _accountMap.begin();
/* Loop on the account map previously loaded */
while (iter != _accountMap.end()) {
if (iter->second) {
if (iter->second->isEnabled()) {
_debug ("Register account %s", iter->first.c_str());
status = iter->second->registerVoIPLink();
if (status != 0) {
flag = false;
}
}
}
iter++;
}
audioLayerMutexLock();
// calls the client notification here in case of errors at startup...
if (_audiodriver->getErrorMessage() != -1) {
notifyErrClient (_audiodriver->getErrorMessage());
}
audioLayerMutexUnlock();
if (flag)
return 0;
else
return 1;
}
//THREAD=Main
int
ManagerImpl::initRegisterAccounts()
{
int status;
bool flag = true;
AccountMap::iterator iter;
_debugInit ("Manager: Initiate VoIP Links Registration");
iter = _accountMap.begin();
/* Loop on the account map previously loaded */
while (iter != _accountMap.end()) {
for (iter = _accountMap.begin(); iter != _accountMap.end(); ++iter) {
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 != 0) {
flag = false;
}
}
if (iter->second->isEnabled())
iter->second->registerVoIPLink();
}
iter++;
}
audioLayerMutexLock();
// calls the client notification here in case of errors at startup...
if (_audiodriver->getErrorMessage() != -1) {
if (_audiodriver->getErrorMessage() != -1)
notifyErrClient (_audiodriver->getErrorMessage());
}
audioLayerMutexUnlock();
if (flag)
return 0;
else
return 1;
audioLayerMutexUnlock();
}
VoIPLink* ManagerImpl::getAccountLink (const std::string& accountID) const
{
if (not accountID.empty()) {