diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index e55330067189ccbf2d3a5fa7a8b13a2a1e59919c..8d259ff77aa227355ad47bdb51b90e126b091914 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -42,13 +42,15 @@
 #include "manager.h"
 #include <pwd.h>
 #include <sstream>
+#include <stdlib.h>
 
 const char * const SIPAccount::IP2IP_PROFILE = "IP2IP";
 const char * const SIPAccount::OVERRTP_STR = "overrtp";
 const char * const SIPAccount::SIPINFO_STR = "sipinfo";
 
 namespace {
-    const int MIN_REGISTRATION_TIME = 600;
+    const int MIN_REGISTRATION_TIME = 60;
+    const int DEFAULT_REGISTRATION_TIME = 3600;
 }
 
 SIPAccount::SIPAccount(const std::string& accountID)
@@ -97,6 +99,7 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , zrtpNotSuppWarning_(true)
     , registrationStateDetailed_()
     , keepAliveTimer_()
+    , keepAliveTimerActive_(false)
     , link_(SIPVoIPLink::instance())
     , receivedParameter_()
     , rPort_(-1)
@@ -402,7 +405,6 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     localPort_ = atoi(details[CONFIG_LOCAL_PORT].c_str());
     publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str());
     if (stunServer_ != details[CONFIG_STUN_SERVER]) {
-        DEBUG("Stun server changed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
         link_->sipTransport.destroyStunResolver(stunServer_);
         // pj_stun_sock_destroy(pj_stun_sock *stun_sock);
     }
@@ -410,6 +412,8 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     stunEnabled_ = details[CONFIG_STUN_ENABLE] == "true";
     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];
 
@@ -585,7 +589,13 @@ void SIPAccount::startKeepAliveTimer() {
     if (isTlsEnabled())
         return;
 
-    DEBUG("SIP ACCOUNT: start keep alive timer");
+    if (isIP2IP())
+        return;
+
+    if(keepAliveTimerActive_)
+        return;
+
+    DEBUG("SipAccount: start keep alive timer for account %s", getAccountID().c_str());
 
     // make sure here we have an entirely new timer
     memset(&keepAliveTimer_, 0, sizeof(pj_timer_entry));
@@ -593,25 +603,31 @@ void SIPAccount::startKeepAliveTimer() {
     pj_time_val keepAliveDelay_;
     keepAliveTimer_.cb = &SIPAccount::keepAliveRegistrationCb;
     keepAliveTimer_.user_data = this;
+    keepAliveTimer_.id = rand();
 
     // expiration may be undetermined during the first registration request
     if (registrationExpire_ == 0) {
-        DEBUG("Registration Expire == 0, take 60");
-        keepAliveDelay_.sec = 60;
+        DEBUG("SipAccount: Registration Expire: 0, taking 60 instead");
+        keepAliveDelay_.sec = 3600;
     }
     else {
-        DEBUG("Registration Expire == %d", registrationExpire_);
-        keepAliveDelay_.sec = registrationExpire_;
+        DEBUG("SipAccount: Registration Expire: %d", registrationExpire_);
+        keepAliveDelay_.sec = registrationExpire_ + MIN_REGISTRATION_TIME;
     }
 
-
     keepAliveDelay_.msec = 0;
 
+    keepAliveTimerActive_ = true;
+
     link_->registerKeepAliveTimer(keepAliveTimer_, keepAliveDelay_);
 }
 
 void SIPAccount::stopKeepAliveTimer() {
-     link_->cancelKeepAliveTimer(keepAliveTimer_);
+    DEBUG("SipAccount: stop keep alive timer %d for account %s", keepAliveTimer_.id, getAccountID().c_str());
+
+    keepAliveTimerActive_ = false;
+
+    link_->cancelKeepAliveTimer(keepAliveTimer_);
 }
 
 pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum(const std::string& method)
@@ -677,7 +693,7 @@ void SIPAccount::initStunConfiguration()
 void SIPAccount::loadConfig()
 {
     if (registrationExpire_ == 0)
-        registrationExpire_ = MIN_REGISTRATION_TIME; /** Default expire value for registration */
+        registrationExpire_ = DEFAULT_REGISTRATION_TIME; /** Default expire value for registration */
 
     if (tlsEnable_ == "true") {
         initTlsConfiguration();
@@ -837,6 +853,8 @@ void SIPAccount::keepAliveRegistrationCb(UNUSED pj_timer_heap_t *th, pj_timer_en
 {
     SIPAccount *sipAccount = static_cast<SIPAccount *>(te->user_data);
 
+    ERROR("SipAccount: Keep alive registration callback for account %s", sipAccount->getAccountID().c_str());
+
     if (sipAccount == NULL) {
         ERROR("Sip account is NULL while registering a new keep alive timer");
         return;
@@ -850,16 +868,10 @@ void SIPAccount::keepAliveRegistrationCb(UNUSED pj_timer_heap_t *th, pj_timer_en
     if (sipAccount->isTlsEnabled())
         return;
 
-    if (sipAccount->isRegistered()) {
-        // send a new register request
-        sipAccount->registerVoIPLink();
+    sipAccount->stopKeepAliveTimer();
 
-        // make sure the current timer is deactivated
-        sipAccount->stopKeepAliveTimer();
-
-        // register a new timer
-        sipAccount->startKeepAliveTimer();
-    }
+    if (sipAccount->isRegistered())
+        sipAccount->registerVoIPLink();
 }
 
 namespace {
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index 6b97d5b1cc49aa8a5736d45ee8f18b4568e3f830..733eb24185edc6765db1005a1edea70b6bc15a25 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -736,6 +736,8 @@ class SIPAccount : public Account {
          */
         pj_timer_entry keepAliveTimer_;
 
+        bool keepAliveTimerActive_;
+
 
         /**
          * Voice over IP Link contains a listener thread and calls
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index e85bc66236dc14f1812043ea86f4ff5cdd5f9077..1dc9c62250745c6e30371bd2f5ac8f2954b8f2dd 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -618,6 +618,8 @@ void SIPVoIPLink::sendUnregister(Account *a)
 
 void SIPVoIPLink::registerKeepAliveTimer(pj_timer_entry &timer, pj_time_val &delay)
 {
+    DEBUG("UserAgent: Register new keep alive timer %d with delay %d", timer.id, delay.sec);
+
     if (timer.id == -1)
         WARN("UserAgent: Timer already scheduled");
 
@@ -1586,19 +1588,36 @@ void update_contact_header(pjsip_regc_cbparam *param, SIPAccount *account)
     pj_pool_release(pool);
 }
 
-void lookForReceivedParameter(pjsip_regc_cbparam *param, SIPAccount *account)
+static void lookForReceivedParameter(pjsip_regc_cbparam *param, SIPAccount *account)
 {
     pj_str_t receivedValue = param->rdata->msg_info.via->recvd_param;
 
     if (receivedValue.slen) {
         std::string publicIpFromReceived(receivedValue.ptr, receivedValue.slen);
-        DEBUG("Cool received received parameter... uhhh?, the value is %s", publicIpFromReceived.c_str());
         account->setReceivedParameter(publicIpFromReceived);
     }
 
     account->setRPort(param->rdata->msg_info.via->rport_param);
 }
 
+static void processRegistrationError(pjsip_regc_cbparam *param, SIPAccount *account, const RegistrationState &state)
+{
+    if(param == NULL) {
+        ERROR("UserAgent: param is NULL while processing registration error");
+        return;
+    }
+
+    if(account == NULL) {
+        ERROR("UserAgent: Account is NULL while processing registration error");
+        return;
+    }
+
+    account->stopKeepAliveTimer();
+    account->setRegistrationState(ErrorAuth);
+    account->setRegister(false);
+    SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
+}
+
 void registration_cb(pjsip_regc_cbparam *param)
 {
     if (param == NULL) {
@@ -1607,12 +1626,13 @@ void registration_cb(pjsip_regc_cbparam *param)
     }
 
     SIPAccount *account = static_cast<SIPAccount *>(param->token);
-
     if (account == NULL) {
         ERROR("SipVoipLink: account doesn't exist in registration callback");
         return;
     }
 
+    std::string accountid = account->getAccountID();
+
     if (account->isContactUpdateEnabled())
         update_contact_header(param, account);
 
@@ -1628,47 +1648,52 @@ void registration_cb(pjsip_regc_cbparam *param)
     }
 
     if (param->status != PJ_SUCCESS) {
-        account->setRegistrationState(ErrorAuth);
-        account->setRegister(false);
-        SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
+        ERROR("UserAgent: Could not register account %s with error %d", accountid.c_str(), param->code);
+        processRegistrationError(param, account, ErrorAuth);
         return;
     }
 
     if (param->code < 0 || param->code >= 300) {
         switch (param->code) {
-            case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE:
-                lookForReceivedParameter(param, account);
-                account->setRegistrationState(ErrorNotAcceptable);
-                SIPVoIPLink::instance()->sendRegister(account);
+            case PJSIP_SC_MULTIPLE_CHOICES: // 300
+            case PJSIP_SC_MOVED_PERMANENTLY: // 301
+            case PJSIP_SC_MOVED_TEMPORARILY: // 302
+            case PJSIP_SC_USE_PROXY: // 305
+            case PJSIP_SC_ALTERNATIVE_SERVICE: // 380
+                ERROR("UserAgent: Could not register account %s with error %d", accountid.c_str(), param->code);
+                processRegistrationError(param, account, Error);
                 break;
-
-            case PJSIP_SC_SERVICE_UNAVAILABLE:
-            case PJSIP_SC_REQUEST_TIMEOUT:
-                account->setRegistrationState(ErrorHost);
-                account->setRegister(false);
-                SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
+            case PJSIP_SC_SERVICE_UNAVAILABLE: // 503
+                ERROR("UserAgent: Could not register account %s with error %d", accountid.c_str(), param->code);
+                processRegistrationError(param, account, ErrorHost);
                 break;
-
-            case PJSIP_SC_UNAUTHORIZED:
-            case PJSIP_SC_FORBIDDEN:
-            case PJSIP_SC_NOT_FOUND:
-                account->setRegistrationState(ErrorAuth);
-                account->setRegister(false);
-                SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
+            case PJSIP_SC_UNAUTHORIZED: // 401
+                // Automatically answered by PJSIP
+                account->registerVoIPLink();
                 break;
-
-            case PJSIP_SC_INTERVAL_TOO_BRIEF:
+            case PJSIP_SC_FORBIDDEN: // 403
+            case PJSIP_SC_NOT_FOUND: // 404
+                ERROR("UserAgent: Could not register account %s with error %d", accountid.c_str(), param->code);
+                processRegistrationError(param, account, ErrorAuth);
+                break;
+            case PJSIP_SC_REQUEST_TIMEOUT: // 408
+                ERROR("UserAgent: Could not register account %s with error %d", accountid.c_str(), param->code);
+                processRegistrationError(param, account, ErrorHost);
+                break;
+            case PJSIP_SC_INTERVAL_TOO_BRIEF: // 423
                 // Expiration Interval Too Brief
                 account->doubleRegistrationExpire();
                 account->registerVoIPLink();
                 account->setRegister(false);
-                SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
                 break;
-
+            case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE: // 606
+                lookForReceivedParameter(param, account);
+                account->setRegistrationState(ErrorNotAcceptable);
+                account->registerVoIPLink();
+                break;
             default:
-                account->setRegistrationState(Error);
-                account->setRegister(false);
-                SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
+                ERROR("UserAgent: Could not register account %s with error %d", param->code);
+                processRegistrationError(param, account, Error);
                 break;
         }
 
diff --git a/gnome/src/actions.c b/gnome/src/actions.c
index 911502eb6be96521acb0d48b771c6c8d9940911b..a5487e3b5bfb34212a54be6d02f82c9cf9e62153 100644
--- a/gnome/src/actions.c
+++ b/gnome/src/actions.c
@@ -749,16 +749,24 @@ sflphone_place_call(callable_obj_t * c)
 {
     account_t * account = NULL;
 
-    DEBUG("Actions: Placing call with %s @ %s and accountid %s", c->_display_name, c->_peer_number, c->_accountID);
-
-    if (c->_state != CALL_STATE_DIALING)
+    if(c == NULL) {
+        ERROR("Actions: Callable object is NULL while making new call");
         return -1;
+    }
+
+    DEBUG("Actions: Placing call from %s to %s using account %s", c->_display_name, c->_peer_number, c->_accountID);
 
-    if (!*c->_peer_number)
+    if (c->_state != CALL_STATE_DIALING) {
+        ERROR("Actions: Call not in state dialing, cannot place call");
         return -1;
+    }
 
-    DEBUG("Actions: Get account for this call");
+    if (!c->_peer_number || strlen(c->_peer_number) == 0) {
+        ERROR("Actions: No peer number set for this call");
+        return -1;
+    }
 
+    // Get the account for this call
     if (strlen(c->_accountID) != 0) {
         DEBUG("Actions: Account %s already set for this call", c->_accountID);
         account = account_list_get_by_id(c->_accountID);
@@ -767,30 +775,31 @@ sflphone_place_call(callable_obj_t * c)
         account = account_list_get_current();
     }
 
-    if (account == NULL) {
-        DEBUG("Actions: Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID);
-        return -1;
+    // Make sure the previously found account is registered, take first one registered elsewhere
+    if (account) {
+        gpointer status = g_hash_table_lookup(account->properties, "Status");
+        if (!utf8_case_equal(status, "REGISTERED")) {
+            // Place the call with the first registered account
+            account = account_list_get_by_state(ACCOUNT_STATE_REGISTERED);
+        }
     }
 
-    gpointer status = g_hash_table_lookup(account->properties, "Status");
-    if (utf8_case_equal(status, "REGISTERED")) {
-        /* The call is made with the current account */
-        // free memory for previous account id and get a new one
-        g_free(c->_accountID);
-        c->_accountID = g_strdup(account->accountID);
-        dbus_place_call(c);
-    } else {
-        /* Place the call with the first registered account
-         * and switch the current account.
-         * If we are here, we can be sure that there is at least one.
-         */
-        account = account_list_get_by_state(ACCOUNT_STATE_REGISTERED);
-        g_free(c->_accountID);
-        c->_accountID = g_strdup(account->accountID);
-        dbus_place_call(c);
-        notify_current_account(account);
+    // If there is no account specified or found, fallback on IP2IP call
+    if(account == NULL) {
+        DEBUG("Actions: Could not find an account for this call, making ip to ip call");
+        account = account_list_get_by_id("IP2IP");
+        if (account == NULL) {
+            ERROR("Actions: Could not determine any account for this call");
+            return -1;
+        }
     }
 
+    // free memory for previous account id and use the new one in case it changed
+    g_free(c->_accountID);
+    c->_accountID = g_strdup(account->accountID);
+    dbus_place_call(c);
+    notify_current_account(account);
+
     c->_history_state = g_strdup(OUTGOING_STRING);
 
     return 0;