From 173a40fde0a9384c873612685f346df2772f0370 Mon Sep 17 00:00:00 2001
From: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
Date: Fri, 10 Aug 2012 18:50:49 -0400
Subject: [PATCH] * #14568: gnome: auto answer feature working

The setting itself is stored in the daemon (and persists in the config
file), but it is up to the client to use it.
---
 daemon/src/account.cpp                 |   2 +
 daemon/src/account.h                   |   4 +
 daemon/src/account_schema.h            |   1 +
 daemon/src/managerimpl.cpp             |   9 +-
 daemon/src/sip/sipaccount.cpp          |  90 ++++++++++----------
 gnome/src/account_schema.h             | 111 +++++++++++++------------
 gnome/src/accountlist.c                |   5 ++
 gnome/src/accountlist.h                |   1 +
 gnome/src/actions.c                    |   5 ++
 gnome/src/config/accountconfigdialog.c |   3 +-
 gnome/src/contacts/calltab.c           |   7 ++
 gnome/src/contacts/calltab.h           |   3 +
 12 files changed, 142 insertions(+), 99 deletions(-)

diff --git a/daemon/src/account.cpp b/daemon/src/account.cpp
index 3db92c30ad..7a99629cd4 100644
--- a/daemon/src/account.cpp
+++ b/daemon/src/account.cpp
@@ -59,6 +59,7 @@ const char * const Account::AUTHENTICATION_USERNAME_KEY = "authenticationUsernam
 const char * const Account::PASSWORD_KEY =          "password";
 const char * const Account::HOSTNAME_KEY =          "hostname";
 const char * const Account::ACCOUNT_ENABLE_KEY =    "enable";
+const char * const Account::ACCOUNT_AUTOANSWER_KEY =    "autoAnswer";
 const char * const Account::MAILBOX_KEY =           "mailbox";
 
 using std::map;
@@ -72,6 +73,7 @@ Account::Account(const string &accountID, const string &type) :
     , hostname_()
     , alias_()
     , enabled_(true)
+    , autoAnswerEnabled_(false)
     , type_(type)
     , registrationState_(UNREGISTERED)
     , audioCodecList_()
diff --git a/daemon/src/account.h b/daemon/src/account.h
index 788340bb0e..52ad18eff4 100644
--- a/daemon/src/account.h
+++ b/daemon/src/account.h
@@ -211,6 +211,7 @@ class Account : public Serializable {
         static const char * const PASSWORD_KEY;
         static const char * const HOSTNAME_KEY;
         static const char * const ACCOUNT_ENABLE_KEY;
+        static const char * const ACCOUNT_AUTOANSWER_KEY;
         static const char * const MAILBOX_KEY;
 
         static std::string mapStateNumberToString(RegistrationState state);
@@ -242,6 +243,9 @@ class Account : public Serializable {
          */
         bool enabled_;
 
+        /* If true, automatically answer calls to this account */
+        bool autoAnswerEnabled_;
+
         /*
          * The account type
          * IAX2 or SIP
diff --git a/daemon/src/account_schema.h b/daemon/src/account_schema.h
index 46d1b436fc..626053d853 100644
--- a/daemon/src/account_schema.h
+++ b/daemon/src/account_schema.h
@@ -45,6 +45,7 @@ static const char *const CONFIG_ACCOUNT_TYPE                    = "Account.type"
 static const char *const CONFIG_ACCOUNT_ALIAS                   = "Account.alias";
 static const char *const CONFIG_ACCOUNT_MAILBOX                 = "Account.mailbox";
 static const char *const CONFIG_ACCOUNT_ENABLE                  = "Account.enable";
+static const char *const CONFIG_ACCOUNT_AUTOANSWER              = "Account.autoAnswer";
 static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE     = "Account.registrationExpire";
 static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS     = "Account.registrationStatus";
 static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index e14613ec3f..03c7d9bfa9 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -1359,11 +1359,12 @@ void ManagerImpl::removeWaitingCall(const std::string& id)
 void ManagerImpl::incomingCall(Call &call, const std::string& accountId)
 {
     stopTone();
+    const std::string callID(call.getCallId());
 
-    associateCallToAccount(call.getCallId(), accountId);
+    associateCallToAccount(callID, accountId);
 
     if (accountId.empty())
-        setIPToIPForCall(call.getCallId(), true);
+        setIPToIPForCall(callID, true);
     else {
         // strip sip: which is not required and bring confusion with ip to ip calls
         // when placing new call from history (if call is IAX, do nothing)
@@ -1381,12 +1382,12 @@ void ManagerImpl::incomingCall(Call &call, const std::string& accountId)
         ringtone(accountId);
     }
 
-    addWaitingCall(call.getCallId());
+    addWaitingCall(callID);
 
     std::string number(call.getPeerNumber());
 
     std::string from("<" + number + ">");
-    dbus_.getCallManager()->incomingCall(accountId, call.getCallId(), call.getDisplayName() + " " + from);
+    dbus_.getCallManager()->incomingCall(accountId, callID, call.getDisplayName() + " " + from);
 }
 
 
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 84b5b1d1ad..a7d6c22624 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -58,6 +58,8 @@ const char * const SIPAccount::SIPINFO_STR = "sipinfo";
 namespace {
     const int MIN_REGISTRATION_TIME = 60;
     const int DEFAULT_REGISTRATION_TIME = 3600;
+    const char *const TRUE_STR = "true";
+    const char *const FALSE_STR = "false";
 }
 
 SIPAccount::SIPAccount(const std::string& accountID)
@@ -83,7 +85,7 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , stunServerName_()
     , stunPort_(PJ_STUN_PORT)
     , dtmfType_(OVERRTP_STR)
-    , tlsEnable_("false")
+    , tlsEnable_(FALSE_STR)
     , tlsCaListFile_()
     , tlsCertificateFile_()
     , tlsPrivateKeyFile_()
@@ -133,6 +135,7 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     ScalarNode alias(Account::alias_);
     ScalarNode hostname(Account::hostname_);
     ScalarNode enable(enabled_);
+    ScalarNode autoAnswer(autoAnswerEnabled_);
     ScalarNode type(Account::type_);
     std::stringstream registrationExpireStr;
     registrationExpireStr << registrationExpire_;
@@ -210,6 +213,7 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     accountmap.setKeyValue(USERNAME_KEY, &username);
     accountmap.setKeyValue(HOSTNAME_KEY, &hostname);
     accountmap.setKeyValue(ACCOUNT_ENABLE_KEY, &enable);
+    accountmap.setKeyValue(ACCOUNT_AUTOANSWER_KEY, &autoAnswer);
     accountmap.setKeyValue(MAILBOX_KEY, &mailbox);
     accountmap.setKeyValue(Preferences::REGISTRATION_EXPIRE_KEY, &expire);
     accountmap.setKeyValue(INTERFACE_KEY, &interface);
@@ -309,6 +313,7 @@ void SIPAccount::unserialize(const Conf::MappingNode &mapNode)
     mapNode.getValue(USERNAME_KEY, &username_);
     if (not isIP2IP()) mapNode.getValue(HOSTNAME_KEY, &hostname_);
     mapNode.getValue(ACCOUNT_ENABLE_KEY, &enabled_);
+    mapNode.getValue(ACCOUNT_AUTOANSWER_KEY, &autoAnswerEnabled_);
     if (not isIP2IP()) mapNode.getValue(MAILBOX_KEY, &mailBox_);
     mapNode.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
     // Update codec list which one is used for SDP offer
@@ -460,7 +465,6 @@ void SIPAccount::unserialize(const Conf::MappingNode &mapNode)
     }
 }
 
-
 void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
 {
     // Account setting common to SIP and IAX
@@ -468,9 +472,10 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     type_ = details[CONFIG_ACCOUNT_TYPE];
     username_ = details[CONFIG_ACCOUNT_USERNAME];
     hostname_ = details[CONFIG_ACCOUNT_HOSTNAME];
-    enabled_ = details[CONFIG_ACCOUNT_ENABLE] == "true";
+    enabled_ = details[CONFIG_ACCOUNT_ENABLE] == TRUE_STR;
+    autoAnswerEnabled_ = details[CONFIG_ACCOUNT_AUTOANSWER] == TRUE_STR;
     ringtonePath_ = details[CONFIG_RINGTONE_PATH];
-    ringtoneEnabled_ = details[CONFIG_RINGTONE_ENABLED] == "true";
+    ringtoneEnabled_ = details[CONFIG_RINGTONE_ENABLED] == TRUE_STR;
     mailBox_ = details[CONFIG_ACCOUNT_MAILBOX];
 
     // SIP specific account settings
@@ -479,7 +484,7 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     displayName_ = details[CONFIG_DISPLAY_NAME];
     serviceRoute_ = details[CONFIG_ACCOUNT_ROUTESET];
     interface_ = details[CONFIG_LOCAL_INTERFACE];
-    publishedSameasLocal_ = details[CONFIG_PUBLISHED_SAMEAS_LOCAL] == "true";
+    publishedSameasLocal_ = details[CONFIG_PUBLISHED_SAMEAS_LOCAL] == TRUE_STR;
     publishedIpAddress_ = details[CONFIG_PUBLISHED_ADDRESS];
     localPort_ = atoi(details[CONFIG_LOCAL_PORT].c_str());
     publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str());
@@ -488,22 +493,22 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
         // pj_stun_sock_destroy(pj_stun_sock *stun_sock);
     }
     stunServer_ = details[CONFIG_STUN_SERVER];
-    stunEnabled_ = details[CONFIG_STUN_ENABLE] == "true";
+    stunEnabled_ = details[CONFIG_STUN_ENABLE] == TRUE_STR;
     dtmfType_ = details[CONFIG_ACCOUNT_DTMF_TYPE];
     registrationExpire_ = atoi(details[CONFIG_ACCOUNT_REGISTRATION_EXPIRE].c_str());
     if(registrationExpire_ < MIN_REGISTRATION_TIME)
         registrationExpire_ = MIN_REGISTRATION_TIME;
 
     userAgent_ = details[CONFIG_ACCOUNT_USERAGENT];
-    keepAliveEnabled_ = details[CONFIG_KEEP_ALIVE_ENABLED] == "true";
+    keepAliveEnabled_ = details[CONFIG_KEEP_ALIVE_ENABLED] == TRUE_STR;
 
     // srtp settings
-    srtpEnabled_ = details[CONFIG_SRTP_ENABLE] == "true";
-    srtpFallback_ = details[CONFIG_SRTP_RTP_FALLBACK] == "true";
-    zrtpDisplaySas_ = details[CONFIG_ZRTP_DISPLAY_SAS] == "true";
-    zrtpDisplaySasOnce_ = details[CONFIG_ZRTP_DISPLAY_SAS_ONCE] == "true";
-    zrtpNotSuppWarning_ = details[CONFIG_ZRTP_NOT_SUPP_WARNING] == "true";
-    zrtpHelloHash_ = details[CONFIG_ZRTP_HELLO_HASH] == "true";
+    srtpEnabled_ = details[CONFIG_SRTP_ENABLE] == TRUE_STR;
+    srtpFallback_ = details[CONFIG_SRTP_RTP_FALLBACK] == TRUE_STR;
+    zrtpDisplaySas_ = details[CONFIG_ZRTP_DISPLAY_SAS] == TRUE_STR;
+    zrtpDisplaySasOnce_ = details[CONFIG_ZRTP_DISPLAY_SAS_ONCE] == TRUE_STR;
+    zrtpNotSuppWarning_ = details[CONFIG_ZRTP_NOT_SUPP_WARNING] == TRUE_STR;
+    zrtpHelloHash_ = details[CONFIG_ZRTP_HELLO_HASH] == TRUE_STR;
     srtpKeyExchange_ = details[CONFIG_SRTP_KEY_EXCHANGE];
 
     // TLS settings
@@ -516,9 +521,9 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     tlsMethod_ = details[CONFIG_TLS_METHOD];
     tlsCiphers_ = details[CONFIG_TLS_CIPHERS];
     tlsServerName_ = details[CONFIG_TLS_SERVER_NAME];
-    tlsVerifyServer_ = details[CONFIG_TLS_VERIFY_SERVER] == "true";
-    tlsVerifyClient_ = details[CONFIG_TLS_VERIFY_CLIENT] == "true";
-    tlsRequireClientCertificate_ = details[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] == "true";
+    tlsVerifyServer_ = details[CONFIG_TLS_VERIFY_SERVER] == TRUE_STR;
+    tlsVerifyClient_ = details[CONFIG_TLS_VERIFY_CLIENT] == TRUE_STR;
+    tlsRequireClientCertificate_ = details[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] == TRUE_STR;
     tlsNegotiationTimeoutSec_ = details[CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC];
     tlsNegotiationTimeoutMsec_ = details[CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC];
 
@@ -541,13 +546,14 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     // note: The IP2IP profile will always have IP2IP as an alias
     a[CONFIG_ACCOUNT_ALIAS] = alias_;
 
-    a[CONFIG_ACCOUNT_ENABLE] = enabled_ ? "true" : "false";
+    a[CONFIG_ACCOUNT_ENABLE] = enabled_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ACCOUNT_AUTOANSWER]= autoAnswerEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_ACCOUNT_TYPE] = type_;
     a[CONFIG_ACCOUNT_HOSTNAME] = hostname_;
     a[CONFIG_ACCOUNT_USERNAME] = username_;
 
     a[CONFIG_RINGTONE_PATH] = ringtonePath_;
-    a[CONFIG_RINGTONE_ENABLED] = ringtoneEnabled_ ? "true" : "false";
+    a[CONFIG_RINGTONE_ENABLED] = ringtoneEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_ACCOUNT_MAILBOX] = mailBox_;
 
     RegistrationState state = UNREGISTERED;
@@ -577,7 +583,7 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     registrationExpireStr << registrationExpire_;
     a[CONFIG_ACCOUNT_REGISTRATION_EXPIRE] = registrationExpireStr.str();
     a[CONFIG_LOCAL_INTERFACE] = interface_;
-    a[CONFIG_PUBLISHED_SAMEAS_LOCAL] = publishedSameasLocal_ ? "true" : "false";
+    a[CONFIG_PUBLISHED_SAMEAS_LOCAL] = publishedSameasLocal_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_PUBLISHED_ADDRESS] = publishedIpAddress_;
 
     std::stringstream localport;
@@ -586,19 +592,19 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     std::stringstream publishedport;
     publishedport << publishedPort_;
     a[CONFIG_PUBLISHED_PORT] = publishedport.str();
-    a[CONFIG_STUN_ENABLE] = stunEnabled_ ? "true" : "false";
+    a[CONFIG_STUN_ENABLE] = stunEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_STUN_SERVER] = stunServer_;
     a[CONFIG_ACCOUNT_DTMF_TYPE] = dtmfType_;
-    a[CONFIG_KEEP_ALIVE_ENABLED] = keepAliveEnabled_ ? "true" : "false";
+    a[CONFIG_KEEP_ALIVE_ENABLED] = keepAliveEnabled_ ? TRUE_STR : FALSE_STR;
 
     a[CONFIG_SRTP_KEY_EXCHANGE] = srtpKeyExchange_;
-    a[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? "true" : "false";
-    a[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? "true" : "false";
+    a[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? TRUE_STR : FALSE_STR;
 
-    a[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? "true" : "false";
-    a[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? "true" : "false";
-    a[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? "true" : "false";
-    a[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? "true" : "false";
+    a[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? TRUE_STR : FALSE_STR;
 
     // TLS listener is unique and parameters are modified through IP2IP_PROFILE
     std::stringstream tlslistenerport;
@@ -612,9 +618,9 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     a[CONFIG_TLS_METHOD] = tlsMethod_;
     a[CONFIG_TLS_CIPHERS] = tlsCiphers_;
     a[CONFIG_TLS_SERVER_NAME] = tlsServerName_;
-    a[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? "true" : "false";
-    a[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? "true" : "false";
-    a[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? "true" : "false";
+    a[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC] = tlsNegotiationTimeoutSec_;
     a[CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC] = tlsNegotiationTimeoutMsec_;
 
@@ -627,7 +633,7 @@ void SIPAccount::registerVoIPLink()
         return;
 
     // Init TLS settings if the user wants to use TLS
-    if (tlsEnable_ == "true") {
+    if (tlsEnable_ == TRUE_STR) {
         DEBUG("TLS is enabled for account %s", accountID_.c_str());
         transportType_ = PJSIP_TRANSPORT_TLS;
         initTlsConfiguration();
@@ -791,7 +797,7 @@ void SIPAccount::loadConfig()
     if (registrationExpire_ == 0)
         registrationExpire_ = DEFAULT_REGISTRATION_TIME; /** Default expire value for registration */
 
-    if (tlsEnable_ == "true") {
+    if (tlsEnable_ == TRUE_STR) {
         initTlsConfiguration();
         transportType_ = PJSIP_TRANSPORT_TLS;
     } else
@@ -1100,12 +1106,12 @@ std::map<std::string, std::string> SIPAccount::getIp2IpDetails() const
     std::map<std::string, std::string> ip2ipAccountDetails;
     ip2ipAccountDetails[CONFIG_ACCOUNT_ID] = IP2IP_PROFILE;
     ip2ipAccountDetails[CONFIG_SRTP_KEY_EXCHANGE] = srtpKeyExchange_;
-    ip2ipAccountDetails[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? "true" : "false";
-    ip2ipAccountDetails[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? "true" : "false";
-    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? "true" : "false";
-    ip2ipAccountDetails[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? "true" : "false";
-    ip2ipAccountDetails[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? "true" : "false";
-    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? "true" : "false";
+    ip2ipAccountDetails[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? TRUE_STR : FALSE_STR;
     ip2ipAccountDetails[CONFIG_LOCAL_INTERFACE] = interface_;
     std::stringstream portstr;
     portstr << localPort_;
@@ -1134,9 +1140,9 @@ std::map<std::string, std::string> SIPAccount::getTlsSettings() const
     tlsSettings[CONFIG_TLS_METHOD] = tlsMethod_;
     tlsSettings[CONFIG_TLS_CIPHERS] = tlsCiphers_;
     tlsSettings[CONFIG_TLS_SERVER_NAME] = tlsServerName_;
-    tlsSettings[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? "true" : "false";
-    tlsSettings[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? "true" : "false";
-    tlsSettings[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? "true" : "false";
+    tlsSettings[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? TRUE_STR : FALSE_STR;
+    tlsSettings[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? TRUE_STR : FALSE_STR;
+    tlsSettings[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? TRUE_STR : FALSE_STR;
     tlsSettings[CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC] = tlsNegotiationTimeoutSec_;
     tlsSettings[CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC] = tlsNegotiationTimeoutMsec_;
 
@@ -1157,7 +1163,7 @@ void set_opt(const std::map<std::string, std::string> &details, const char *key,
     std::map<std::string, std::string>::const_iterator it = details.find(key);
 
     if (it != details.end())
-        val = it->second == "true";
+        val = it->second == TRUE_STR;
 }
 
 void set_opt(const std::map<std::string, std::string> &details, const char *key, pj_uint16_t &val)
diff --git a/gnome/src/account_schema.h b/gnome/src/account_schema.h
index 08ee27a4d3..112b540f13 100644
--- a/gnome/src/account_schema.h
+++ b/gnome/src/account_schema.h
@@ -38,69 +38,76 @@
  */
 
 // Account identifier
-static const char *const CONFIG_ACCOUNT_ID                   = "Account.id";
+static const char *const CONFIG_ACCOUNT_ID                      = "Account.id";
 
 // Common account parameters
-static const char *const CONFIG_ACCOUNT_TYPE                 = "Account.type";
-static const char *const CONFIG_ACCOUNT_ALIAS                = "Account.alias";
-static const char *const CONFIG_ACCOUNT_MAILBOX              = "Account.mailbox";
-static const char *const CONFIG_ACCOUNT_ENABLE               = "Account.enable";
-static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE  = "Account.registrationExpire";
-static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
+static const char *const CONFIG_ACCOUNT_TYPE                    = "Account.type";
+static const char *const CONFIG_ACCOUNT_ALIAS                   = "Account.alias";
+static const char *const CONFIG_ACCOUNT_MAILBOX                 = "Account.mailbox";
+static const char *const CONFIG_ACCOUNT_ENABLE                  = "Account.enable";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE     = "Account.registrationExpire";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS     = "Account.registrationStatus";
 static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
 static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
-static const char *const CONFIG_CREDENTIAL_NUMBER            = "Credential.count";
-static const char *const CONFIG_ACCOUNT_DTMF_TYPE            = "Account.dtmfType";
-static const char *const CONFIG_RINGTONE_PATH                = "Account.ringtonePath";
-static const char *const CONFIG_RINGTONE_ENABLED             = "Account.ringtoneEnabled";
-static const char *const CONFIG_KEEP_ALIVE_ENABLED           = "Account.keepAliveEnabled";
+static const char *const CONFIG_CREDENTIAL_NUMBER               = "Credential.count";
+static const char *const CONFIG_ACCOUNT_DTMF_TYPE               = "Account.dtmfType";
+static const char *const CONFIG_RINGTONE_PATH                   = "Account.ringtonePath";
+static const char *const CONFIG_RINGTONE_ENABLED                = "Account.ringtoneEnabled";
+static const char *const CONFIG_KEEP_ALIVE_ENABLED              = "Account.keepAliveEnabled";
 
-static const char *const CONFIG_ACCOUNT_HOSTNAME             = "Account.hostname";
-static const char *const CONFIG_ACCOUNT_USERNAME             = "Account.username";
-static const char *const CONFIG_ACCOUNT_ROUTESET             = "Account.routeset";
-static const char *const CONFIG_ACCOUNT_PASSWORD             = "Account.password";
-static const char *const CONFIG_ACCOUNT_REALM                = "Account.realm";
-static const char *const CONFIG_ACCOUNT_DEFAULT_REALM        = "*";
-static const char *const CONFIG_ACCOUNT_USERAGENT            = "Account.useragent";
 
-static const char *const CONFIG_LOCAL_INTERFACE              = "Account.localInterface";
-static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL       = "Account.publishedSameAsLocal";
-static const char *const CONFIG_LOCAL_PORT                   = "Account.localPort";
-static const char *const CONFIG_PUBLISHED_PORT               = "Account.publishedPort";
-static const char *const CONFIG_PUBLISHED_ADDRESS            = "Account.publishedAddress";
+static const char *const CONFIG_DEFAULT_REGISTRATION_EXPIRE     = "60";
 
-static const char *const CONFIG_DISPLAY_NAME                 = "Account.displayName";
-static const char *const CONFIG_DEFAULT_ADDRESS              = "0.0.0.0";
+static const char *const CONFIG_ACCOUNT_HOSTNAME                = "Account.hostname";
+static const char *const CONFIG_ACCOUNT_USERNAME                = "Account.username";
+static const char *const CONFIG_ACCOUNT_ROUTESET                = "Account.routeset";
+static const char *const CONFIG_ACCOUNT_PASSWORD                = "Account.password";
+static const char *const CONFIG_ACCOUNT_REALM                   = "Account.realm";
+static const char *const CONFIG_ACCOUNT_DEFAULT_REALM           = "*";
+static const char *const CONFIG_ACCOUNT_USERAGENT               = "Account.useragent";
+static const char *const CONFIG_ACCOUNT_AUTOANSWER              = "Account.autoAnswer";
+
+static const char *const CONFIG_LOCAL_INTERFACE                 = "Account.localInterface";
+static const char *const CONFIG_INTERFACE                       = "Account.interface";
+static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL          = "Account.publishedSameAsLocal";
+static const char *const CONFIG_LOCAL_PORT                      = "Account.localPort";
+static const char *const CONFIG_PUBLISHED_PORT                  = "Account.publishedPort";
+static const char *const CONFIG_PUBLISHED_ADDRESS               = "Account.publishedAddress";
+static const char *const CONFIG_DEFAULT_LOCAL_PORT              = "5060";
+static const char *const CONFIG_DEFAULT_PUBLISHED_PORT          = "5060";
+static const char *const CONFIG_DEFAULT_PUBLISHED_SAMEAS_LOCAL  = "true";
+static const char *const CONFIG_DEFAULT_INTERFACE               = "default";
+
+static const char *const CONFIG_DISPLAY_NAME                    = "Account.displayName";
+static const char *const CONFIG_DEFAULT_ADDRESS                 = "0.0.0.0";
 
 // SIP specific parameters
-static const char *const CONFIG_SIP_PROXY                    = "SIP.proxy";
-static const char *const CONFIG_SIP_AUTOANSWER               = "SIP.autoAnswer";
-static const char *const CONFIG_STUN_SERVER                  = "STUN.server";
-static const char *const CONFIG_STUN_ENABLE                  = "STUN.enable";
+static const char *const CONFIG_STUN_SERVER                     = "STUN.server";
+static const char *const CONFIG_STUN_ENABLE                     = "STUN.enable";
 
 // SRTP specific parameters
-static const char *const CONFIG_SRTP_ENABLE                  = "SRTP.enable";
-static const char *const CONFIG_SRTP_KEY_EXCHANGE            = "SRTP.keyExchange";
-static const char *const CONFIG_SRTP_ENCRYPTION_ALGO         = "SRTP.encryptionAlgorithm";  // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
-static const char *const CONFIG_SRTP_RTP_FALLBACK            = "SRTP.rtpFallback";
-static const char *const CONFIG_ZRTP_HELLO_HASH              = "ZRTP.helloHashEnable";
-static const char *const CONFIG_ZRTP_DISPLAY_SAS             = "ZRTP.displaySAS";
-static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING        = "ZRTP.notSuppWarning";
-static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE        = "ZRTP.displaySasOnce";
+static const char *const CONFIG_SRTP_ENABLE                     = "SRTP.enable";
+static const char *const CONFIG_SRTP_KEY_EXCHANGE               = "SRTP.keyExchange";
+static const char *const CONFIG_SRTP_ENCRYPTION_ALGO            = "SRTP.encryptionAlgorithm";  // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
+static const char *const CONFIG_SRTP_RTP_FALLBACK               = "SRTP.rtpFallback";
+static const char *const CONFIG_ZRTP_HELLO_HASH                 = "ZRTP.helloHashEnable";
+static const char *const CONFIG_ZRTP_DISPLAY_SAS                = "ZRTP.displaySAS";
+static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING           = "ZRTP.notSuppWarning";
+static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE           = "ZRTP.displaySasOnce";
 
-static const char *const CONFIG_TLS_LISTENER_PORT            = "TLS.listenerPort";
-static const char *const CONFIG_TLS_ENABLE                   = "TLS.enable";
-static const char *const CONFIG_TLS_CA_LIST_FILE             = "TLS.certificateListFile";
-static const char *const CONFIG_TLS_CERTIFICATE_FILE         = "TLS.certificateFile";
-static const char *const CONFIG_TLS_PRIVATE_KEY_FILE         = "TLS.privateKeyFile";
-static const char *const CONFIG_TLS_PASSWORD                 = "TLS.password";
-static const char *const CONFIG_TLS_METHOD                   = "TLS.method";
-static const char *const CONFIG_TLS_CIPHERS                  = "TLS.ciphers";
-static const char *const CONFIG_TLS_SERVER_NAME              = "TLS.serverName";
-static const char *const CONFIG_TLS_VERIFY_SERVER            = "TLS.verifyServer";
-static const char *const CONFIG_TLS_VERIFY_CLIENT            = "TLS.verifyClient";
-static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireClientCertificate";
-static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC  = "TLS.negotiationTimeoutSec";
-static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
+static const char *const CONFIG_TLS_LISTENER_PORT               = "TLS.listenerPort";
+static const char *const CONFIG_TLS_ENABLE                      = "TLS.enable";
+static const char *const CONFIG_TLS_CA_LIST_FILE                = "TLS.certificateListFile";
+static const char *const CONFIG_TLS_CERTIFICATE_FILE            = "TLS.certificateFile";
+static const char *const CONFIG_TLS_PRIVATE_KEY_FILE            = "TLS.privateKeyFile";
+static const char *const CONFIG_TLS_PASSWORD                    = "TLS.password";
+static const char *const CONFIG_TLS_METHOD                      = "TLS.method";
+static const char *const CONFIG_TLS_CIPHERS                     = "TLS.ciphers";
+static const char *const CONFIG_TLS_SERVER_NAME                 = "TLS.serverName";
+static const char *const CONFIG_TLS_VERIFY_SERVER               = "TLS.verifyServer";
+static const char *const CONFIG_TLS_VERIFY_CLIENT               = "TLS.verifyClient";
+static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE  = "TLS.requireClientCertificate";
+static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC     = "TLS.negotiationTimeoutSec";
+static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC    = "TLS.negotiationTimemoutMsec";
 
 #endif
diff --git a/gnome/src/accountlist.c b/gnome/src/accountlist.c
index 2f2901fc10..29034dbf1b 100644
--- a/gnome/src/accountlist.c
+++ b/gnome/src/accountlist.c
@@ -303,6 +303,11 @@ gboolean current_account_has_new_message(void)
     return current && current->_messages_number > 0;
 }
 
+gboolean account_has_autoanswer_on(const account_t *account)
+{
+    return g_strcmp0(account_lookup(account, CONFIG_ACCOUNT_AUTOANSWER), "true") == 0;
+}
+
 gboolean account_is_IP2IP(const account_t *account)
 {
     g_assert(account);
diff --git a/gnome/src/accountlist.h b/gnome/src/accountlist.h
index 6395421303..1b0f2a08e6 100644
--- a/gnome/src/accountlist.h
+++ b/gnome/src/accountlist.h
@@ -183,6 +183,7 @@ void current_account_set_message_number(guint nb);
 
 gboolean current_account_has_new_message(void);
 
+gboolean account_has_autoanswer_on(const account_t *account);
 gboolean account_is_IP2IP(const account_t *account);
 gboolean account_is_SIP(const account_t *account);
 gboolean account_is_IAX(const account_t *account);
diff --git a/gnome/src/actions.c b/gnome/src/actions.c
index 8f7b04752a..bdb037fb1a 100644
--- a/gnome/src/actions.c
+++ b/gnome/src/actions.c
@@ -513,6 +513,11 @@ sflphone_incoming_call(callable_obj_t * c)
         statusbar_push_message(msg , NULL, __MSG_ACCOUNT_DEFAULT);
         g_free(msg);
     }
+    account_t *account = account_list_get_by_id(c->_accountID);
+    if (account_has_autoanswer_on(account)) {
+        calltab_set_selected_call(active_calltree_tab, c);
+        sflphone_pick_up();
+    }
 }
 
 static void
diff --git a/gnome/src/config/accountconfigdialog.c b/gnome/src/config/accountconfigdialog.c
index b477217e1c..ce2414a73b 100644
--- a/gnome/src/config/accountconfigdialog.c
+++ b/gnome/src/config/accountconfigdialog.c
@@ -127,7 +127,7 @@ static void reset()
 static void
 auto_answer_cb(GtkToggleButton *widget, account_t *account)
 {
-    account_replace(account, CONFIG_SIP_AUTOANSWER,
+    account_replace(account, CONFIG_ACCOUNT_AUTOANSWER,
                     gtk_toggle_button_get_active(widget) ? "true" : "false");
 }
 
@@ -379,6 +379,7 @@ create_basic_tab(account_t *account)
 
     row++;
     GtkWidget *auto_answer_checkbox = gtk_check_button_new_with_mnemonic(_("_Auto-answer calls"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_answer_checkbox), account_has_autoanswer_on(account));
     g_signal_connect(auto_answer_checkbox, "toggled", G_CALLBACK(auto_answer_cb), account);
     gtk_table_attach(GTK_TABLE(table), auto_answer_checkbox, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
diff --git a/gnome/src/contacts/calltab.c b/gnome/src/contacts/calltab.c
index 741830918a..d0a8bf9e4d 100644
--- a/gnome/src/contacts/calltab.c
+++ b/gnome/src/contacts/calltab.c
@@ -80,6 +80,13 @@ calltab_get_selected_type(calltab_t* tab)
     return tab->selectedType;
 }
 
+void
+calltab_set_selected_call(calltab_t *tab, callable_obj_t *call)
+{
+    g_assert(tab);
+    tab->selectedCall = call;
+}
+
 callable_obj_t *
 calltab_get_selected_call(calltab_t *tab)
 {
diff --git a/gnome/src/contacts/calltab.h b/gnome/src/contacts/calltab.h
index 7797e6e8d4..9fd5ee44d1 100644
--- a/gnome/src/contacts/calltab.h
+++ b/gnome/src/contacts/calltab.h
@@ -59,6 +59,9 @@ calltab_get_selected_type (calltab_t *);
 callable_obj_t *
 calltab_get_selected_call (calltab_t *);
 
+void
+calltab_set_selected_call (calltab_t *, callable_obj_t *call);
+
 conference_obj_t *
 calltab_get_selected_conf (calltab_t *);
 
-- 
GitLab