From 981ba725c69a4da70d89bc74f73f12360b67a7ca Mon Sep 17 00:00:00 2001
From: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
Date: Tue, 25 Sep 2007 17:29:45 -0400
Subject: [PATCH] Remove the 'AUTO_REGISTER' parameter. Major clean-up of
 registration process.

Now, there should be only an 'Enabled' toggle for each account. It determines
if the account is registered on start-up AND if it's enabled, generally.

TODO: We'll need another parameter, to select which account is the one used
to do calls. Anyways, it wasn't very convenient to use the 'First one enabled',
since you'll often want multiple accounts enabled, and be able to select which
account to use for an outgoing call.

This commit updates the SFLphone daemon and the Gtk+ client.

It removes a whole bunch of useless variables (_state, _shouldInitOnStart,
_shouldRegisterOnStart, _registered). Now the registration state is fetched
directly from the VoIPLink (when called from the Account). So, no more
duplication of statuses.

TODO: SFLphone-gtk will need to support the TRYING and ERROR messages as
'Status' reply.
---
 sflphone-gtk/src/accountlist.h   |  2 +-
 sflphone-gtk/src/accountwindow.c | 16 ++++----
 src/account.cpp                  |  7 +---
 src/account.h                    | 58 ++++++++---------------------
 src/iaxaccount.cpp               | 47 +++++++++---------------
 src/iaxaccount.h                 |  4 +-
 src/iaxvoiplink.cpp              | 29 ++++++++++++---
 src/managerimpl.cpp              | 40 +++++++++++---------
 src/sipaccount.cpp               | 63 +++++++++++++-------------------
 src/sipaccount.h                 |  4 +-
 src/sipvoiplink.cpp              | 18 ++++++---
 src/sipvoiplink.h                |  2 +-
 src/voiplink.cpp                 |  2 +-
 src/voiplink.h                   | 14 ++++++-
 14 files changed, 145 insertions(+), 161 deletions(-)

diff --git a/sflphone-gtk/src/accountlist.h b/sflphone-gtk/src/accountlist.h
index 56d0d016dd..62ffff1059 100644
--- a/sflphone-gtk/src/accountlist.h
+++ b/sflphone-gtk/src/accountlist.h
@@ -28,7 +28,7 @@
 #define ACCOUNT_TYPE               "Account.type"
 #define ACCOUNT_ALIAS              "Account.alias"
 #define ACCOUNT_ENABLED            "Account.enable"
-#define ACCOUNT_REGISTER           "Account.autoregister"
+//#define ACCOUNT_REGISTER           "Account.autoregister"
 
 #define ACCOUNT_SIP_FULL_NAME      "SIP.fullName"
 #define ACCOUNT_SIP_HOST_PART      "SIP.hostPart"
diff --git a/sflphone-gtk/src/accountwindow.c b/sflphone-gtk/src/accountwindow.c
index ce1a8d3e93..dc0ab9919f 100644
--- a/sflphone-gtk/src/accountwindow.c
+++ b/sflphone-gtk/src/accountwindow.c
@@ -34,7 +34,7 @@ GtkWidget * entryID;
 GtkWidget * entryName;
 GtkWidget * entryProtocol;
 GtkWidget * entryEnabled;
-GtkWidget * entryRegister;
+//GtkWidget * entryRegister;
 GtkWidget * entryFullName;
 GtkWidget * entryUserPart;
 GtkWidget * entryHostPart;
@@ -142,10 +142,10 @@ show_account_window (account_t * a)
     strcmp(g_hash_table_lookup(currentAccount->properties, ACCOUNT_ENABLED),"TRUE") == 0 ? TRUE: FALSE); 
   gtk_table_attach ( GTK_TABLE( table ), entryEnabled, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
   
-  entryRegister = gtk_check_button_new_with_mnemonic("_Register on startup ");
-  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entryRegister), 
-    strcmp(g_hash_table_lookup(currentAccount->properties, ACCOUNT_REGISTER),"TRUE") == 0 ? TRUE: FALSE); 
-  gtk_table_attach ( GTK_TABLE( table ), entryRegister, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+  //entryRegister = gtk_check_button_new_with_mnemonic("_Register on startup ");
+  //gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entryRegister), 
+  //  strcmp(g_hash_table_lookup(currentAccount->properties, ACCOUNT_REGISTER),"TRUE") == 0 ? TRUE: FALSE); 
+  //gtk_table_attach ( GTK_TABLE( table ), entryRegister, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
   
   label = gtk_label_new_with_mnemonic ("_Alias:");
   gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -252,9 +252,9 @@ show_account_window (account_t * a)
     g_hash_table_replace(currentAccount->properties, 
       g_strdup(ACCOUNT_ENABLED), 
       g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entryEnabled)) ? "TRUE": "FALSE"));
-    g_hash_table_replace(currentAccount->properties, 
-      g_strdup(ACCOUNT_REGISTER), 
-      g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entryRegister)) ? "TRUE": "FALSE"));
+    // g_hash_table_replace(currentAccount->properties, 
+    //  g_strdup(ACCOUNT_REGISTER), 
+    //  g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entryRegister)) ? "TRUE": "FALSE"));
     /* TODO Add SIP/IAX when IAX is ok */  
     g_hash_table_replace(currentAccount->properties, 
       g_strdup(ACCOUNT_ALIAS), 
diff --git a/src/account.cpp b/src/account.cpp
index c83697569b..e05fafb0fe 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -25,11 +25,7 @@ Account::Account(const AccountID& accountID) : _accountID(accountID)
 {
   _link = NULL;
 
-  _shouldInitOnStart = false;
-  _shouldRegisterOnStart = false;
   _enabled = false;
-  _registered = false;
-  _state = false;
 }
 
 
@@ -57,7 +53,6 @@ Account::initConfig(Conf::ConfigTree& config) {
 void
 Account::loadConfig() 
 {
-  _shouldInitOnStart = Manager::instance().getConfigInt(_accountID, CONFIG_ACCOUNT_ENABLE) ? true : false;
-  _shouldRegisterOnStart = Manager::instance().getConfigInt(_accountID, CONFIG_ACCOUNT_AUTO_REGISTER) ? true : false;
+  _enabled = Manager::instance().getConfigInt(_accountID, CONFIG_ACCOUNT_ENABLE) ? true : false;
 }
 
diff --git a/src/account.h b/src/account.h
index 7d87cc1189..e09437652c 100644
--- a/src/account.h
+++ b/src/account.h
@@ -21,6 +21,7 @@
 
 #include <string>
 #include "config/config.h"
+#include "voiplink.h"
 
 class VoIPLink;
 
@@ -28,7 +29,7 @@ typedef std::string AccountID;
 #define AccountNULL ""
 #define CONFIG_ACCOUNT_TYPE   "Account.type"
 #define CONFIG_ACCOUNT_ENABLE "Account.enable"
-#define CONFIG_ACCOUNT_AUTO_REGISTER  "Account.autoregister"
+//#define CONFIG_ACCOUNT_AUTO_REGISTER  "Account.autoregister"
 #define CONFIG_ACCOUNT_ALIAS  "Account.alias"
 
 #define IAX_FULL_NAME         "IAX.fullName"
@@ -85,16 +86,20 @@ class Account{
   /**
    * Register the underlying VoIPLink
    *
+   * This should update the getRegistrationState() return value.
+   *
    * @return false is an error occurs
    */
-  virtual bool registerVoIPLink() = 0;
+  virtual void registerVoIPLink() = 0;
 
   /**
    * Unregister the underlying VoIPLink
    *
+   * This should update the getRegistrationState() return value.
+   *
    * @return false is an error occurs
    */
-  virtual bool unregisterVoIPLink() = 0;
+  virtual void unregisterVoIPLink() = 0;
 
   /**
    * Init the voiplink to run (event listener)
@@ -109,27 +114,14 @@ class Account{
   virtual bool terminate() = 0;
 
   /**
-   * Tell if we should init the account on start
-   * @return true if we must init the link
-   */
-  bool shouldInitOnStart() {return _shouldInitOnStart; }
-
-  /**
-   * Tell if we should register the account on start
-   * @return true if we must register the account
-   */
-  bool shouldRegisterOnStart() {return _shouldRegisterOnStart; }
-
-  /**
-   * Tell if the account is enable or not
+   * Tell if the account is enable or not. See doc for _enabled.
    */
   bool isEnabled() { return _enabled; }
 
   /**
-   * Tell if the latest registration succeed or failed 
+   * Return registration state of underlying VoIPLink
    */
-  bool setState(bool state) { _state = state; }
-  bool getState() { return _state; }
+  VoIPLink::RegistrationState getRegistrationState() { return _link->getRegistrationState(); }
 
 private:
 
@@ -145,34 +137,14 @@ protected:
   VoIPLink* _link;
 
   /**
-   * Tells if the link should be start on loading or not
+   * Tells if the link is enabled, active.
+   *
+   * This implies the link will be initialized on startup.
+   *
    * Modified by the configuration (key: ENABLED)
    */
-  bool _shouldInitOnStart;
-
-  /**
-   * Tells if we should register automatically on startup
-   * Modified by the configuration (key: AUTO-REGISTER)
-   */
-  bool _shouldRegisterOnStart;
-
-  /**
-   * Tells if the link is enabled or not.
-   * Modified by init/terminate
-   */
   bool _enabled;
 
-  /**
-   * Tells if the link is registered or not.
-   * Modified by unregister/register
-   */
-  bool _registered;
-
-  /**
-   * The latest registration was a success or not
-   */
-  bool _state;
-
 };
 
 #endif
diff --git a/src/iaxaccount.cpp b/src/iaxaccount.cpp
index b2af855bf2..8241a544b2 100644
--- a/src/iaxaccount.cpp
+++ b/src/iaxaccount.cpp
@@ -34,53 +34,40 @@ IAXAccount::~IAXAccount()
   delete _link;
 }
 
-bool
+void
 IAXAccount::registerVoIPLink()
 {
-  if (_link && !_registered) {
-    init();
-    //unregisterAccount(); No need to unregister first.
-    IAXVoIPLink* tmplink = dynamic_cast<IAXVoIPLink*> (_link);
-    if (tmplink) {
-      // Stuff needed for IAX registration
-      tmplink->setHost(Manager::instance().getConfigString(_accountID, IAX_HOST));
-      tmplink->setUser(Manager::instance().getConfigString(_accountID, IAX_USER));
-      tmplink->setPass(Manager::instance().getConfigString(_accountID, IAX_PASS));
-    }
-    _registered = _link->sendRegister();
+  init();
+  //unregisterAccount(); No need to unregister first.
+  IAXVoIPLink* thislink = dynamic_cast<IAXVoIPLink*> (_link);
+  if (thislink) {
+    // Stuff needed for IAX registration
+    thislink->setHost(Manager::instance().getConfigString(_accountID, IAX_HOST));
+    thislink->setUser(Manager::instance().getConfigString(_accountID, IAX_USER));
+    thislink->setPass(Manager::instance().getConfigString(_accountID, IAX_PASS));
   }
-  return _registered;
+
+  _link->sendRegister();
 }
 
-bool
+void
 IAXAccount::unregisterVoIPLink()
 {
-  if (_link && _registered) {
-    _registered = _link->sendUnregister();
-  }
-  return !_registered;
+  _link->sendUnregister();
 }
 
 bool
 IAXAccount::init()
 {
-  if (_link && !_enabled) {
-    _link->init();
-    _enabled = true;
-    return true;
-  }
-  return false;
+  _link->init();
+  return true;
 }
 
 bool
 IAXAccount::terminate()
 {
-  if (_link && _enabled) {
-    _link->terminate();
-    _enabled = false;
-    return true;
-  }
-  return false;
+  _link->terminate();
+  return true;
 }
 
 void 
diff --git a/src/iaxaccount.h b/src/iaxaccount.h
index f8fee48208..e1812d6c6c 100644
--- a/src/iaxaccount.h
+++ b/src/iaxaccount.h
@@ -38,8 +38,8 @@ public:
   void initConfig(Conf::ConfigTree& config);
   /** Actually unuseful, since config loading is done in init() */
   void loadConfig();
-  bool registerVoIPLink();
-  bool unregisterVoIPLink();
+  void registerVoIPLink();
+  void unregisterVoIPLink();
   bool init();
   bool terminate();
 
diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp
index 385911434b..a2923f15d9 100644
--- a/src/iaxvoiplink.cpp
+++ b/src/iaxvoiplink.cpp
@@ -100,6 +100,10 @@ IAXVoIPLink::~IAXVoIPLink()
 bool
 IAXVoIPLink::init()
 {
+  // If it was done, don't do it again, until we call terminate()
+  if (_initDone)
+    return false;
+
   bool returnValue = false;
   //_localAddress = "127.0.0.1";
   // port 0 is default
@@ -128,9 +132,13 @@ IAXVoIPLink::init()
       break;
     }
     nbTry--;
+
+    _initDone = true;
   }
   if (port == IAX_FAILURE || nbTry==0) {
     _debug("Fail to initialize iax\n");
+    
+    _initDone = false;
   }
   return returnValue;
 }
@@ -138,10 +146,16 @@ IAXVoIPLink::init()
 void
 IAXVoIPLink::terminate()
 {
-//  iaxc_shutdown();  
-//  hangup all call
-    terminateIAXCall();
-//  iax_hangup(calls[callNo].session,"Dumped Call");
+  // If it was done, don't do it again, until we call init()
+  if (!_initDone)
+    return;
+
+  // iaxc_shutdown();  
+
+  // Hangup all calls
+  terminateIAXCall();
+
+  _initDone = false;
 }
 
 void
@@ -154,7 +168,7 @@ IAXVoIPLink::terminateIAXCall()
     call = dynamic_cast<IAXCall*>(iter->second);
     if (call) {
       _mutexIAX.enterMutex();
-      iax_hangup(call->getSession(),"Dumped Call");
+      iax_hangup(call->getSession(), "Dumped Call");
       _mutexIAX.leaveMutex();
       call->setSession(NULL);
       delete call; call = NULL;
@@ -407,6 +421,8 @@ IAXVoIPLink::sendRegister()
     // until we unregister.
     _nextRefreshStamp = time(NULL) + 10;
     result = true;
+
+    setRegistrationState(Trying);
   }
 
   // unlock
@@ -432,6 +448,9 @@ IAXVoIPLink::sendUnregister()
     _regSession = NULL;
   }
   _nextRefreshStamp = 0;
+
+  setRegistrationState(Unregistered);
+
   return false;
 }
 
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 4de4a07369..9c46cec91c 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -428,8 +428,8 @@ ManagerImpl::initRegisterAccounts()
   while( iter != _accountMap.end() ) {
     if ( iter->second) {
       iter->second->loadConfig();
-      if ( iter->second->shouldInitOnStart() ) {
-        if ( iter->second->init() && iter->second->shouldRegisterOnStart()) {
+      if ( iter->second->isEnabled() ) {
+        if ( iter->second->init() ) {
             iter->second->registerVoIPLink();
         }
         // init only the first account -- naahh..
@@ -442,11 +442,12 @@ ManagerImpl::initRegisterAccounts()
 }
 
 //THREAD=Main
+// Currently unused
 bool
 ManagerImpl::registerAccount(const AccountID& accountId)
 {
-  _debug("Register VoIP Link\n");
-  int returnValue = false;
+  _debug("Register one VoIP Link\n");
+
   // right now, we don't support two SIP account
   // so we close everything before registring a new account
   Account* account = getAccount(accountId);
@@ -459,21 +460,22 @@ ManagerImpl::registerAccount(const AccountID& accountId)
       }
       iter++;
     }
-    returnValue = account->registerVoIPLink();
+    account->registerVoIPLink();
   }
-  return returnValue;
+  return true;
 }
 
 //THREAD=Main
+// Currently unused
 bool 
 ManagerImpl::unregisterAccount(const AccountID& accountId)
 {
-  _debug("Unregister VoIP Link\n");
-  int returnValue = false;
+  _debug("Unregister one VoIP Link\n");
+
   if (accountExists( accountId ) ) {
-    returnValue = getAccount(accountId)->unregisterVoIPLink();
+    getAccount(accountId)->unregisterVoIPLink();
   }
-  return returnValue;
+  return true;
 }
 
 //THREAD=Main
@@ -779,7 +781,7 @@ ManagerImpl::registrationSucceed(const AccountID& accountid)
 {
   Account* acc = getAccount(accountid);
  if ( acc ) { 
-    acc->setState(true); 
+    //acc->setState(true); 
     if (_dbus) _dbus->getConfigurationManager()->accountsChanged();
   }
 }
@@ -790,7 +792,7 @@ ManagerImpl::registrationFailed(const AccountID& accountid)
 {
   Account* acc = getAccount(accountid);
   if ( acc ) { 
-    acc->setState(false);
+    //acc->setState(false);
     if (_dbus) _dbus->getConfigurationManager()->accountsChanged();
   }
 }
@@ -1556,6 +1558,7 @@ ManagerImpl::getAccountDetails(const AccountID& accountID)
 {
   std::map<std::string, std::string> a;
   std::string accountType;
+  enum VoIPLink::RegistrationState state = _accountMap[accountID]->getRegistrationState();
     
   accountType = getConfigString(accountID, CONFIG_ACCOUNT_TYPE);
 
@@ -1565,12 +1568,12 @@ ManagerImpl::getAccountDetails(const AccountID& accountID)
       getConfigString(accountID, CONFIG_ACCOUNT_ALIAS)
       )
     );
-  a.insert(
+  /*a.insert(
     std::pair<std::string, std::string>(
       CONFIG_ACCOUNT_AUTO_REGISTER, 
       getConfigString(accountID, CONFIG_ACCOUNT_AUTO_REGISTER)== "1" ? "TRUE": "FALSE"
       )
-    );
+    );*/
   a.insert(
     std::pair<std::string, std::string>(
       CONFIG_ACCOUNT_ENABLE, 
@@ -1580,7 +1583,10 @@ ManagerImpl::getAccountDetails(const AccountID& accountID)
   a.insert(
     std::pair<std::string, std::string>(
       "Status", 
-      _accountMap[accountID]->getState() ? "REGISTERED": "UNREGISTERED"
+      (state == VoIPLink::Registered ? "REGISTERED":
+       (state == VoIPLink::Unregistered ? "UNREGISTERED":
+	(state == VoIPLink::Trying ? "TRYING":
+	 (state == VoIPLink::Error ? "ERROR": "UNKNOWN"))))
       )
     );
   a.insert(
@@ -1680,8 +1686,8 @@ ManagerImpl::setAccountDetails( const ::DBus::String& accountID,
   std::string accountType = (*details.find(CONFIG_ACCOUNT_TYPE)).second;
     
   setConfig(accountID, CONFIG_ACCOUNT_ALIAS, (*details.find(CONFIG_ACCOUNT_ALIAS)).second);
-  setConfig(accountID, CONFIG_ACCOUNT_AUTO_REGISTER, 
-	    (*details.find(CONFIG_ACCOUNT_AUTO_REGISTER)).second == "TRUE" ? "1": "0" );
+  //setConfig(accountID, CONFIG_ACCOUNT_AUTO_REGISTER, 
+  // (*details.find(CONFIG_ACCOUNT_AUTO_REGISTER)).second == "TRUE" ? "1": "0" );
   setConfig(accountID, CONFIG_ACCOUNT_ENABLE, 
 	    (*details.find(CONFIG_ACCOUNT_ENABLE)).second == "TRUE" ? "1": "0" );
   setConfig(accountID, CONFIG_ACCOUNT_TYPE, accountType);
diff --git a/src/sipaccount.cpp b/src/sipaccount.cpp
index 3bc6a95caf..b277e8eb96 100644
--- a/src/sipaccount.cpp
+++ b/src/sipaccount.cpp
@@ -34,63 +34,50 @@ SIPAccount::~SIPAccount()
   delete _link;
 }
 
-bool
+void
 SIPAccount::registerVoIPLink()
 {
-  if (_link) {
-    init(); // init if not enable
-    unregisterVoIPLink();
-    SIPVoIPLink* tmplink = dynamic_cast<SIPVoIPLink*> (_link);
-    if (tmplink) {
-      // Stuff needed for SIP registration.
-      tmplink->setProxy   (Manager::instance().getConfigString(_accountID,SIP_PROXY));
-      tmplink->setUserPart(Manager::instance().getConfigString(_accountID,SIP_USER_PART));
-      tmplink->setAuthName(Manager::instance().getConfigString(_accountID,SIP_AUTH_NAME));
-      tmplink->setPassword(Manager::instance().getConfigString(_accountID,SIP_PASSWORD));
-    }
-    _registered = _link->sendRegister();
+  init(); // init if not enable
+  unregisterVoIPLink();
+  SIPVoIPLink* thislink = dynamic_cast<SIPVoIPLink*> (_link);
+  if (thislink) {
+    // Stuff needed for SIP registration.
+    thislink->setProxy   (Manager::instance().getConfigString(_accountID,SIP_PROXY));
+    thislink->setUserPart(Manager::instance().getConfigString(_accountID,SIP_USER_PART));
+    thislink->setAuthName(Manager::instance().getConfigString(_accountID,SIP_AUTH_NAME));
+    thislink->setPassword(Manager::instance().getConfigString(_accountID,SIP_PASSWORD));
   }
-  return _registered;
+
+  _link->sendRegister();
 }
 
-bool
+void
 SIPAccount::unregisterVoIPLink()
 {
-  if (_link && _registered) {
-    _registered = _link->sendUnregister();
-  }
-  return !_registered;
+  _link->sendUnregister();
 }
 
 bool
 SIPAccount::init()
 {
-  if (_link && !_enabled) {
-    _link->setFullName(Manager::instance().getConfigString(_accountID,SIP_FULL_NAME));
-    _link->setHostName(Manager::instance().getConfigString(_accountID,SIP_HOST_PART));
-    int useStun = Manager::instance().getConfigInt(_accountID,SIP_USE_STUN);
-    
-    SIPVoIPLink* tmplink = dynamic_cast<SIPVoIPLink*> (_link);
-    if (tmplink) {
-      tmplink->setStunServer(Manager::instance().getConfigString(_accountID,SIP_STUN_SERVER));
-      tmplink->setUseStun( useStun!=0 ? true : false);
-    }
-    _link->init();
-    _enabled = true;
-    return true;
+  _link->setFullName(Manager::instance().getConfigString(_accountID,SIP_FULL_NAME));
+  _link->setHostName(Manager::instance().getConfigString(_accountID,SIP_HOST_PART));
+  int useStun = Manager::instance().getConfigInt(_accountID,SIP_USE_STUN);
+  
+  SIPVoIPLink* thislink = dynamic_cast<SIPVoIPLink*> (_link);
+  if (thislink) {
+    thislink->setStunServer(Manager::instance().getConfigString(_accountID,SIP_STUN_SERVER));
+    thislink->setUseStun( useStun!=0 ? true : false);
   }
-  return false;
+  _link->init();
+  return true;
 }
 
 bool
 SIPAccount::terminate()
 {
-  if (_link && _enabled) {
-    _link->terminate();
-    _enabled = false;
+  _link->terminate();
     return true;
-  }
-  return false;
 }
 
 void 
diff --git a/src/sipaccount.h b/src/sipaccount.h
index c69a333c22..a86346bb41 100644
--- a/src/sipaccount.h
+++ b/src/sipaccount.h
@@ -38,8 +38,8 @@ public:
   void initConfig(Conf::ConfigTree& config);
   /** Actually unuseful, since config loading is done in init() */
   void loadConfig();
-  bool registerVoIPLink();
-  bool unregisterVoIPLink();
+  void registerVoIPLink();
+  void unregisterVoIPLink();
   bool init();
   bool terminate();
 
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index dd8121b4ac..fa531eb28b 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -59,7 +59,6 @@ SIPVoIPLink::SIPVoIPLink(const AccountID& accountID)
 
   _nMsgVoicemail = 0;
   _eXosipRegID = EXOSIP_ERROR_STD;
-  _eXosipStarted = false;
 
   _nbTryListenAddr = 2; // number of times to try to start SIP listener
   _localExternPort = 0;
@@ -77,12 +76,15 @@ SIPVoIPLink::~SIPVoIPLink()
 bool 
 SIPVoIPLink::init()
 {
-  if (!_eXosipStarted) {
+  if (!_initDone) {
     if (0 != eXosip_init()) {
       _debug("! SIP Failure: Could not initialize eXosip\n");
       return false;
     }
-    _eXosipStarted = true;
+
+    // Pour éviter qu'on refasse l'init sans avoir considéré l'erreur,
+    // s'il y en a une ?
+    _initDone = true;
   
     // check networking capabilities
     if ( !checkNetwork() ) {
@@ -140,7 +142,11 @@ SIPVoIPLink::init()
     _debug("  SIP Init: starting loop thread (SIP events)\n");
     _evThread->start();
   }
-  return _eXosipStarted;
+
+  _initDone = true;
+
+  // Useless
+  return true;
 }
 
 
@@ -149,9 +155,9 @@ void
 SIPVoIPLink::terminate()
 {
   terminateSIPCall(); 
-  if (_eXosipStarted) {
+  if (_initDone) {
     eXosip_quit();
-    _eXosipStarted = false;
+    _initDone = false;
   }
 }
 
diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h
index 2b3121b754..215e13ee00 100644
--- a/src/sipvoiplink.h
+++ b/src/sipvoiplink.h
@@ -243,7 +243,7 @@ private:
   /** EventThread get every incoming events */
   EventThread* _evThread;
   /** Tell if eXosip was stared (eXosip_init) */
-  bool _eXosipStarted;
+  bool _initDone;
 
   /** Registration identifier, needed by unregister to build message */
   int _eXosipRegID;
diff --git a/src/voiplink.cpp b/src/voiplink.cpp
index f687485da4..bf678333e4 100644
--- a/src/voiplink.cpp
+++ b/src/voiplink.cpp
@@ -25,7 +25,7 @@
 #include "voiplink.h"
 #include "manager.h"
 
-VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0), _registrationError("")
+VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0), _registrationError(""), _initDone(false)
 {
 }
 
diff --git a/src/voiplink.h b/src/voiplink.h
index db7d141adf..a64c2abefa 100644
--- a/src/voiplink.h
+++ b/src/voiplink.h
@@ -23,13 +23,16 @@
 #define __VOIP_LINK_H__
 
 #include <string>
-#include "account.h" // for AccountID
 #include "call.h"
 #include <map>
 #include <cc++/thread.h> // for mutex
 
 class AudioCodec;
 
+//#include "account.h" // for AccountID
+// replaced by:
+typedef std::string AccountID;
+
 typedef std::map<CallID, Call*> CallMap;
 
 /**
@@ -179,6 +182,7 @@ protected:
 
   /** Contains all the calls for this Link, protected by mutex */
   CallMap _callMap;
+
   /** Mutex to protect call map */
   ost::Mutex _callMapMutex;
 
@@ -186,6 +190,14 @@ protected:
   std::string _localIPAddress;
   /** Get local listening port (5060 for SIP, ...) */
   unsigned int _localPort;
+
+
+  /** Whether init() was called already or not
+   *
+   * This should be used in [IAX|SIP]VoIPLink::init() and terminate(), to
+   * indicate that init() was called, or reset by terminate().
+   */
+  bool _initDone;
 };
 
 #endif // __VOIP_LINK_H__
-- 
GitLab