diff --git a/astylerc b/astylerc
index 7f14310574b90b9d41b3065853175a0edf06b0b6..d38cbbf0f6ed52b6e978ad7e191d9ca8f4102945 100644
--- a/astylerc
+++ b/astylerc
@@ -15,5 +15,4 @@ unpad-paren         # Remove unwanted space around parentheses
 pad-header          # Insert space padding after paren headers only (e.g. 'if', 'for', 'while'...)
 pad-oper            # Insert space padding around operator
 formatted           # only display files that have changed
-recursive           # recursively enter subdirs
 suffix=none         # don't create backup files (that's what version control is for)
diff --git a/daemon/src/account_schema.h b/daemon/src/account_schema.h
index 91359c1d3f243b5a0fdd30cc831a62c81f3d6505..5e72f5f39b6ca1d3eef84f770c8448d448f609f2 100644
--- a/daemon/src/account_schema.h
+++ b/daemon/src/account_schema.h
@@ -67,6 +67,10 @@ static const char *const CONFIG_ACCOUNT_PASSWORD                = "Account.passw
 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_AUDIO_PORT_MIN          = "Account.audioPortMin";
+static const char *const CONFIG_ACCOUNT_AUDIO_PORT_MAX          = "Account.audioPortMax";
+static const char *const CONFIG_ACCOUNT_VIDEO_PORT_MIN          = "Account.videoPortMin";
+static const char *const CONFIG_ACCOUNT_VIDEO_PORT_MAX          = "Account.videoPortMax";
 
 static const char *const CONFIG_LOCAL_INTERFACE                 = "Account.localInterface";
 static const char *const CONFIG_INTERFACE                       = "Account.interface";
diff --git a/daemon/src/audio/alsa/alsalayer.cpp b/daemon/src/audio/alsa/alsalayer.cpp
index 4fb286fd7319c0d2e0e539786af998c139028612..11319d0a17bff314e15879c323a23544371a56ff 100644
--- a/daemon/src/audio/alsa/alsalayer.cpp
+++ b/daemon/src/audio/alsa/alsalayer.cpp
@@ -602,8 +602,9 @@ AlsaLayer::getAudioDeviceIndexMap(bool getCapture) const
                 snd_pcm_info_set_device(pcminfo , 0);
                 snd_pcm_info_set_stream(pcminfo, getCapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK);
 
-                if (snd_ctl_pcm_info(handle ,pcminfo) < 0) {
-                    DEBUG(" Cannot get info");
+                int err;
+                if ((err = snd_ctl_pcm_info(handle ,pcminfo)) < 0) {
+                    WARN("Cannot get info: %s", snd_strerror(err));
                 } else {
                     DEBUG("card %i : %s [%s]",
                           numCard,
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
index f51a08d610f683cc23db5602c098095f44a2e14c..eef438ae5a2a421fa33ed0a5ea6e46956a9dffb8 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
@@ -87,6 +87,7 @@ DTMFEvent::DTMFEvent(char digit) : payload(), newevent(true), length(1000)
     payload.ebit = false; // end of event bit
     payload.rbit = false; // reserved bit
     payload.duration = 1; // duration for this event
+    payload.vol = 10;
 }
 
 AudioRtpRecord::AudioRtpRecord() :
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.cpp b/daemon/src/audio/audiortp/audio_rtp_session.cpp
index 04bce53c96e37413917de5e9bfe566a781dbe191..2fe2c829379cef343079da6de39fbf63bfec186f 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_session.cpp
@@ -117,7 +117,8 @@ void AudioRtpSession::sendDtmfEvent()
     DEBUG("Send RTP Dtmf (%d)", dtmf.payload.event);
 
     const int increment = getIncrementForDTMF();
-    timestamp_ += increment;
+    if (dtmf.newevent)
+        timestamp_ += increment;
 
     // discard equivalent size of audio
     processDataEncode();
@@ -129,7 +130,11 @@ void AudioRtpSession::sendDtmfEvent()
     if (dtmf.newevent)
         queue_.setMark(true);
 
-    queue_.sendImmediate(timestamp_, (const unsigned char *)(& (dtmf.payload)), sizeof(ost::RTPPacket::RFC2833Payload));
+    // Send end packet three times (without changing it). Sequence number is
+    // incremented automatically by ccrtp, which is the correct behaviour.
+    const unsigned repetitions = dtmf.payload.ebit ? 3 : 1;
+    for (unsigned i = 0; i < repetitions; ++i)
+        queue_.sendImmediate(timestamp_, (const unsigned char *)(& (dtmf.payload)), sizeof(ost::RTPPacket::RFC2833Payload));
 
     // This is no longer a new event
     if (dtmf.newevent) {
@@ -145,7 +150,7 @@ void AudioRtpSession::sendDtmfEvent()
     dtmf.length -= increment;
     dtmf.payload.duration++;
 
-    // next packet is going to be the last one
+    // next packet is going to be the end packet (transmitted 3 times)
     if ((dtmf.length - increment) < increment)
         dtmf.payload.ebit = true;
 
diff --git a/daemon/src/audio/pulseaudio/pulselayer.cpp b/daemon/src/audio/pulseaudio/pulselayer.cpp
index 26f59c0b159e1546a90d43f883854f5f1142d6c7..17eb7e4bc5a041b100dee6eda7b778dd71bee87b 100644
--- a/daemon/src/audio/pulseaudio/pulselayer.cpp
+++ b/daemon/src/audio/pulseaudio/pulselayer.cpp
@@ -509,8 +509,8 @@ void PulseLayer::readFromMic()
     const char *data = NULL;
     size_t bytes;
 
-    size_t sample_size = record_->sampleSize();
-    uint8_t channels = record_->channels();
+    const size_t sample_size = record_->sampleSize();
+    const uint8_t channels = record_->channels();
 
     if (pa_stream_peek(record_->pulseStream() , (const void**) &data , &bytes) < 0 or !data)
         return;
@@ -519,7 +519,9 @@ void PulseLayer::readFromMic()
     outfile.write((const char *)data, bytes);
 #endif
 
-    size_t samples = bytes / sample_size;
+    assert(channels);
+    assert(sample_size);
+    const size_t samples = bytes / sample_size / channels;
 
     AudioBuffer in(samples, channels, sampleRate_);
     in.deinterleave((SFLAudioSample*)data, samples, channels);
@@ -527,22 +529,10 @@ void PulseLayer::readFromMic()
     unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer().getInternalSamplingRate();
     bool resample = sampleRate_ != mainBufferSampleRate;
 
-    /*if (resample) {
-        double resampleFactor = (double) sampleRate_ / mainBufferSampleRate;
-        //bytes = (double) bytes * resampleFactor;
-    }*/
-
-    /*if (bytes > mic_buf_size_) {
-        mic_buf_size_ = bytes;
-        delete [] mic_buffer_;
-        mic_buffer_ = new SFLAudioSample[samples];
-    }*/
-
     AudioBuffer * out = &in;
 
     if (resample) {
         mic_buffer_.setSampleRate(mainBufferSampleRate);
-        //converter_.resample((SFLAudioSample*)data, mic_buffer_, samples, mainBufferSampleRate, sampleRate_, samples);
         converter_.resample(in, mic_buffer_);
         out = &mic_buffer_;
     }
diff --git a/daemon/src/audio/samplerateconverter.cpp b/daemon/src/audio/samplerateconverter.cpp
index 337e0df4f654b4c88b87bbeebcc57931434c22e4..fbc32c16647ade82c2c8db23bbacc2985c71ff44 100644
--- a/daemon/src/audio/samplerateconverter.cpp
+++ b/daemon/src/audio/samplerateconverter.cpp
@@ -32,7 +32,7 @@
 #include "sfl_types.h"
 
 SamplerateConverter::SamplerateConverter(int freq, size_t channels /* = 1 */) : floatBufferIn_(),
-    floatBufferOut_(), samples_(0), channels_(channels), maxFreq_(freq), src_state_(0)
+    floatBufferOut_(), scratchBuffer_(), samples_(0), channels_(channels), maxFreq_(freq), src_state_(0)
 {
     int err;
     src_state_ = src_new(SRC_LINEAR, channels_, &err);
@@ -41,6 +41,7 @@ SamplerateConverter::SamplerateConverter(int freq, size_t channels /* = 1 */) :
 
     floatBufferIn_.resize(samples_);
     floatBufferOut_.resize(samples_);
+    scratchBuffer_.resize(samples_);
 }
 
 SamplerateConverter::~SamplerateConverter()
@@ -86,6 +87,7 @@ void SamplerateConverter::resample(const AudioBuffer &dataIn, AudioBuffer &dataO
     samples_ = std::max(inSamples, outSamples);
     floatBufferIn_.resize(inSamples);
     floatBufferOut_.resize(outSamples);
+    scratchBuffer_.resize(outSamples);
 
     SRC_DATA src_data;
     src_data.data_in = floatBufferIn_.data();
@@ -101,9 +103,7 @@ void SamplerateConverter::resample(const AudioBuffer &dataIn, AudioBuffer &dataO
 
     /*
     TODO: one-shot deinterleave and float-to-short conversion
-    currently using floatBufferIn_ as scratch
     */
-    SFLAudioSample *scratch_buff = reinterpret_cast<SFLAudioSample *>(floatBufferIn_.data());
-    src_float_to_short_array(floatBufferOut_.data(), scratch_buff, outSamples);
-    dataOut.deinterleave(scratch_buff, src_data.output_frames, nbChans);
+    src_float_to_short_array(floatBufferOut_.data(), scratchBuffer_.data(), outSamples);
+    dataOut.deinterleave(scratchBuffer_.data(), src_data.output_frames, nbChans);
 }
diff --git a/daemon/src/audio/samplerateconverter.h b/daemon/src/audio/samplerateconverter.h
index 2b533e208347e6359eaf78a511532118659b30e2..41f0e8be5e737940a77598aa000abdd9d4e19d24 100644
--- a/daemon/src/audio/samplerateconverter.h
+++ b/daemon/src/audio/samplerateconverter.h
@@ -78,6 +78,7 @@ class SamplerateConverter {
         /* temporary buffers */
         std::vector<float> floatBufferIn_;
         std::vector<float> floatBufferOut_;
+        std::vector<SFLAudioSample> scratchBuffer_;
 
         size_t samples_; // size in samples of temporary buffers
         size_t channels_; // number of channels configured
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 4fd90f795a516cb46ff57f0e6fbf1b2b5a4f275e..8b19bdf0ed11e2502c21504e7cbcae55989a3f0c 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -2466,9 +2466,14 @@ ManagerImpl::addAccount(const std::map<std::string, std::string>& details)
     /** @todo Deal with both the accountMap_ and the Configuration */
     std::stringstream accountID;
 
+    std::string accountList(preferences.getAccountOrder());
     accountID << "Account:" << time(NULL);
     std::string newAccountID(accountID.str());
 
+    while (accountList.find(newAccountID) != std::string::npos) {
+       newAccountID += "1";
+    }
+
     // Get the type
 
     std::string accountType;
@@ -2501,16 +2506,14 @@ ManagerImpl::addAccount(const std::map<std::string, std::string>& details)
 
     newAccount->setAccountDetails(details);
 
-    // Add the newly created account in the account order list
-    std::string accountList(preferences.getAccountOrder());
 
-    newAccountID += "/";
+    // Add the newly created account in the account order list
     if (not accountList.empty()) {
         // Prepend the new account
-        accountList.insert(0, newAccountID);
+        accountList.insert(0, newAccountID + "/");
         preferences.setAccountOrder(accountList);
     } else {
-        accountList = newAccountID;
+        accountList = newAccountID + "/";
         preferences.setAccountOrder(accountList);
     }
 
@@ -2522,7 +2525,7 @@ ManagerImpl::addAccount(const std::map<std::string, std::string>& details)
 
     client_.getConfigurationManager()->accountsChanged();
 
-    return accountID.str();
+    return newAccountID;
 }
 
 void ManagerImpl::removeAccount(const std::string& accountID)
diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index 64766b9dcb286a64905801ebc93f9aa001046302..ef92c84d5b0fea2d97b2c9b031392c211a4b1910 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -39,6 +39,7 @@
 #include "manager.h"
 
 #include <algorithm>
+#include "sipaccount.h"
 
 #ifdef HAVE_OPUS
 #include "audio/codecs/opus.h"
@@ -64,7 +65,7 @@ Sdp::Sdp(pj_pool_t *pool)
     , video_codec_list_()
     , sessionAudioMedia_()
     , sessionVideoMedia_()
-    , localIpAddr_()
+    , publishedIpAddr_()
     , remoteIpAddr_()
     , localAudioDataPort_(0)
     , localAudioControlPort_(0)
@@ -77,6 +78,14 @@ Sdp::Sdp(pj_pool_t *pool)
     , telephoneEventPayload_(101) // same as asterisk
 {}
 
+Sdp::~Sdp()
+{
+    SIPAccount::releasePort(localAudioDataPort_);
+#ifdef SFL_VIDEO
+    SIPAccount::releasePort(localVideoDataPort_);
+#endif
+}
+
 namespace {
     bool hasPayload(const std::vector<sfl::AudioCodec*> &codecs, int pt)
     {
@@ -258,7 +267,7 @@ Sdp::setMediaDescriptorLines(bool audio)
 #ifdef HAVE_OPUS
         // Opus sample rate is allways declared as 48000 and channel num is allways 2 in rtpmap as per
         // http://tools.ietf.org/html/draft-spittka-payload-rtp-opus-03#section-6.2
-        if(payload == Opus::PAYLOAD_TYPE) {
+        if (payload == Opus::PAYLOAD_TYPE) {
             rtpmap.clock_rate = 48000;
             rtpmap.param.ptr = ((char* const)"2");
             rtpmap.param.slen = 1;
@@ -276,9 +285,9 @@ Sdp::setMediaDescriptorLines(bool audio)
 
 #ifdef HAVE_OPUS
         // Declare stereo support for opus
-        if(payload == Opus::PAYLOAD_TYPE) {
+        if (payload == Opus::PAYLOAD_TYPE) {
             std::ostringstream os;
-            os << "fmtp:" << payload << " stereo=1; sprop-stereo=" << (channels>1 ? 1 : 0);
+            os << "fmtp:" << payload << " stereo=1; sprop-stereo=" << (channels > 1);
             med->attr[med->attr_count++] = pjmedia_sdp_attr_create(memPool_, os.str().c_str(), NULL);
         }
 #endif
@@ -314,7 +323,7 @@ Sdp::setMediaDescriptorLines(bool audio)
 void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
 {
     std::ostringstream os;
-    os << localIpAddr_ << ":" << localAudioControlPort_;
+    os << publishedIpAddr_ << ":" << localAudioControlPort_;
     const std::string str(os.str());
     pj_str_t input_str = pj_str((char*) str.c_str());
     pj_sockaddr outputAddr;
@@ -328,6 +337,18 @@ void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
         pjmedia_sdp_attr_add(&med->attr_count, med->attr, attr);
 }
 
+void
+Sdp::setPublishedIP(const std::string &ip_addr)
+{
+    publishedIpAddr_ = ip_addr;
+    if (localSession_) {
+        localSession_->origin.addr = pj_str((char*) publishedIpAddr_.c_str());
+        localSession_->conn->addr = localSession_->origin.addr;
+        if (pjmedia_sdp_validate(localSession_) != PJ_SUCCESS)
+            ERROR("Could not validate SDP");
+    }
+}
+
 void
 Sdp::updatePorts(const std::vector<pj_sockaddr_in> &sockets)
 {
@@ -335,6 +356,20 @@ Sdp::updatePorts(const std::vector<pj_sockaddr_in> &sockets)
     localAudioControlPort_  = pj_ntohs(sockets[1].sin_port);
     localVideoDataPort_     = pj_ntohs(sockets[2].sin_port);
     localVideoControlPort_  = pj_ntohs(sockets[3].sin_port);
+
+    if (localSession_) {
+        if (localSession_->media[0]) {
+            localSession_->media[0]->desc.port = localAudioDataPort_;
+            // update RTCP attribute
+            if (pjmedia_sdp_media_remove_all_attr(localSession_->media[0], "rtcp"))
+                addRTCPAttribute(localSession_->media[0]);
+        }
+        if (localSession_->media[1])
+            localSession_->media[1]->desc.port = localVideoDataPort_;
+
+        if (not pjmedia_sdp_validate(localSession_))
+            ERROR("Could not validate SDP");
+    }
 }
 
 
@@ -415,7 +450,7 @@ int Sdp::createLocalSession(const vector<int> &selectedAudioCodecs, const vector
     localSession_->origin.id = tv.sec + 2208988800UL;
     localSession_->origin.net_type = pj_str((char*) "IN");
     localSession_->origin.addr_type = pj_str((char*) "IP4");
-    localSession_->origin.addr = pj_str((char*) localIpAddr_.c_str());
+    localSession_->origin.addr = pj_str((char*) publishedIpAddr_.c_str());
 
     localSession_->name = pj_str((char*) PACKAGE);
 
diff --git a/daemon/src/sip/sdp.h b/daemon/src/sip/sdp.h
index 1ac680aebceafe00238ffcff9bc4d9d310e91bab..f6c74f03e51d078e514f2bbb4db7aee887898493 100644
--- a/daemon/src/sip/sdp.h
+++ b/daemon/src/sip/sdp.h
@@ -69,6 +69,8 @@ class Sdp {
          */
         Sdp(pj_pool_t *pool);
 
+        ~Sdp();
+
         /**
          * Accessor for the internal memory pool
          */
@@ -151,15 +153,13 @@ class Sdp {
         /*
          * Write accessor. Set the local IP address that will be used in the sdp session
          */
-        void setLocalIP(const std::string &ip_addr) {
-            localIpAddr_ = ip_addr;
-        }
+        void setPublishedIP(const std::string &ip_addr);
 
         /*
          * Read accessor. Get the local IP address
          */
-        std::string getLocalIP() const {
-            return localIpAddr_;
+        std::string getPublishedIP() const {
+            return publishedIpAddr_;
         }
 
         void setLocalPublishedAudioPort(int port) {
@@ -309,7 +309,7 @@ class Sdp {
         std::vector<sfl::AudioCodec *> sessionAudioMedia_;
         std::vector<std::string> sessionVideoMedia_;
 
-        std::string localIpAddr_;
+        std::string publishedIpAddr_;
         std::string remoteIpAddr_;
 
         int localAudioDataPort_;
diff --git a/daemon/src/sip/sip_utils.cpp b/daemon/src/sip/sip_utils.cpp
index 82a3b07dd334ec9edd000bf0c75cbc1fbafbd717..27dcc33169900178438de9ced29781b449623a90 100644
--- a/daemon/src/sip/sip_utils.cpp
+++ b/daemon/src/sip/sip_utils.cpp
@@ -191,3 +191,16 @@ sip_utils::getIPList(const std::string &name)
     freeaddrinfo(result);
     return ipList;
 }
+
+void
+sip_utils::addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata)
+{
+    pj_str_t pjContact = pj_str((char*) contactStr.c_str());
+
+    pjsip_contact_hdr *contact = pjsip_contact_hdr_create(tdata->pool);
+    contact->uri = pjsip_parse_uri(tdata->pool, pjContact.ptr,
+                                   pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+    // remove old contact header (if present)
+    pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
+    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) contact);
+}
diff --git a/daemon/src/sip/sip_utils.h b/daemon/src/sip/sip_utils.h
index 91cf9e4b41d1064a1eea862c4e446ed2dc952323..32d531db998b5c0145a45c65b85c8fc58a444ab3 100644
--- a/daemon/src/sip/sip_utils.h
+++ b/daemon/src/sip/sip_utils.h
@@ -54,6 +54,8 @@ namespace sip_utils {
     std::string parseDisplayName(const char * buffer);
 
     std::vector<std::string> getIPList(const std::string &name);
+
+    void addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata);
 }
 
 #endif // SIP_UTILS_H_
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 881571ff33f64522b2532807cfc8a79fc2948546..a52f57ff1783568d1512aeaae1bb54af6430babe 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -48,6 +48,8 @@
 #include <sstream>
 #include <algorithm>
 #include <cstdlib>
+#include <array>
+#include <memory>
 
 
 #ifdef SFL_VIDEO
@@ -67,6 +69,9 @@ const char *const TRUE_STR = "true";
 const char *const FALSE_STR = "false";
 }
 
+// we force RTP ports to be even, so we only need HALF_MAX_PORT booleans
+bool SIPAccount::portsInUse_[HALF_MAX_PORT];
+
 SIPAccount::SIPAccount(const std::string& accountID)
     : Account(accountID)
     , transport_(NULL)
@@ -118,9 +123,9 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , receivedParameter_("")
     , rPort_(-1)
     , via_addr_()
-    , audioPortRange_(16384, 32766)
+    , audioPortRange_({16384, 32766})
 #ifdef SFL_VIDEO
-    , videoPortRange_(49152, 65534)
+    , videoPortRange_({49152, (MAX_PORT) - 2})
 #endif
 {
     via_addr_.host.ptr = 0;
@@ -131,11 +136,55 @@ SIPAccount::SIPAccount(const std::string& accountID)
         alias_ = IP2IP_PROFILE;
 }
 
+
 SIPAccount::~SIPAccount()
 {
     delete presence_;
 }
 
+
+namespace {
+std::array<std::unique_ptr<Conf::ScalarNode>, 2>
+serializeRange(Conf::MappingNode &accountMap, const char *minKey, const char *maxKey, const std::pair<uint16_t, uint16_t> &range)
+{
+    using namespace Conf;
+    std::array<std::unique_ptr<ScalarNode>, 2> result;
+
+    std::ostringstream os;
+    os << range.first;
+    result[0].reset(new ScalarNode(os.str()));
+    os.str("");
+    accountMap.setKeyValue(minKey, result[0].get());
+
+    os << range.second;
+    ScalarNode portMax(os.str());
+    result[1].reset(new ScalarNode(os.str()));
+    accountMap.setKeyValue(maxKey, result[1].get());
+    return result;
+}
+
+
+void updateRange(int min, int max, std::pair<uint16_t, uint16_t> &range)
+{
+    if (min > 0 and (max > min) and max <= MAX_PORT - 2) {
+        range.first = min;
+        range.second = max;
+    }
+}
+
+void
+unserializeRange(const Conf::YamlNode &mapNode, const char *minKey, const char *maxKey, std::pair<uint16_t, uint16_t> &range)
+{
+    int tmpMin = 0;
+    int tmpMax = 0;
+    mapNode.getValue(minKey, &tmpMin);
+    mapNode.getValue(maxKey, &tmpMax);
+    updateRange(tmpMin, tmpMax, range);
+}
+}
+
+
+
 void SIPAccount::serialize(Conf::YamlEmitter &emitter)
 {
     using namespace Conf;
@@ -289,6 +338,11 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     ScalarNode userAgent(userAgent_);
     accountmap.setKeyValue(USER_AGENT_KEY, &userAgent);
 
+    auto audioPortNodes(serializeRange(accountmap, AUDIO_PORT_MIN_KEY, AUDIO_PORT_MAX_KEY, audioPortRange_));
+#ifdef SFL_VIDEO
+    auto videoPortNodes(serializeRange(accountmap, VIDEO_PORT_MIN_KEY, VIDEO_PORT_MAX_KEY, videoPortRange_));
+#endif
+
     try {
         emitter.serializeAccount(&accountmap);
     } catch (const YamlEmitterException &e) {
@@ -494,6 +548,11 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
         tlsMap->getValue(TIMEOUT_KEY, &tlsNegotiationTimeoutMsec_);
     }
     mapNode.getValue(USER_AGENT_KEY, &userAgent_);
+
+    unserializeRange(mapNode, AUDIO_PORT_MIN_KEY, AUDIO_PORT_MAX_KEY, audioPortRange_);
+#ifdef SFL_VIDEO
+    unserializeRange(mapNode, VIDEO_PORT_MIN_KEY, VIDEO_PORT_MAX_KEY, videoPortRange_);
+#endif
 }
 
 void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
@@ -535,6 +594,15 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     userAgent_ = details[CONFIG_ACCOUNT_USERAGENT];
     keepAliveEnabled_ = details[CONFIG_KEEP_ALIVE_ENABLED] == TRUE_STR;
 
+    int tmpMin = atoi(details[CONFIG_ACCOUNT_AUDIO_PORT_MIN].c_str());
+    int tmpMax = atoi(details[CONFIG_ACCOUNT_AUDIO_PORT_MAX].c_str());
+    updateRange(tmpMin, tmpMax, audioPortRange_);
+#ifdef SFL_VIDEO
+    tmpMin = atoi(details[CONFIG_ACCOUNT_VIDEO_PORT_MIN].c_str());
+    tmpMax = atoi(details[CONFIG_ACCOUNT_VIDEO_PORT_MAX].c_str());
+    updateRange(tmpMin, tmpMax, videoPortRange_);
+#endif
+
     // srtp settings
     srtpEnabled_ = details[CONFIG_SRTP_ENABLE] == TRUE_STR;
     srtpFallback_ = details[CONFIG_SRTP_RTP_FALLBACK] == TRUE_STR;
@@ -590,6 +658,17 @@ static std::string retrievePassword(const std::map<std::string, std::string>& ma
     return "";
 }
 
+void
+addRangeToDetails(std::map<std::string, std::string> &a, const char *minKey, const char *maxKey, const std::pair<uint16_t, uint16_t> &range)
+{
+    std::ostringstream os;
+    os << range.first;
+    a[minKey] = os.str();
+    os.str("");
+    os << range.second;
+    a[maxKey] = os.str();
+}
+
 std::map<std::string, std::string> SIPAccount::getAccountDetails() const
 {
     std::map<std::string, std::string> a;
@@ -643,6 +722,11 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     a[CONFIG_ACCOUNT_ROUTESET] = serviceRoute_;
     a[CONFIG_ACCOUNT_USERAGENT] = userAgent_;
 
+    addRangeToDetails(a, CONFIG_ACCOUNT_AUDIO_PORT_MIN, CONFIG_ACCOUNT_AUDIO_PORT_MAX, audioPortRange_);
+#ifdef SFL_VIDEO
+    addRangeToDetails(a, CONFIG_ACCOUNT_VIDEO_PORT_MIN, CONFIG_ACCOUNT_VIDEO_PORT_MAX, videoPortRange_);
+#endif
+
     std::stringstream registrationExpireStr;
     registrationExpireStr << registrationExpire_;
     a[CONFIG_ACCOUNT_REGISTRATION_EXPIRE] = registrationExpireStr.str();
@@ -809,7 +893,8 @@ void SIPAccount::trimCiphers()
 {
     int sum = 0;
     int count = 0;
-    // PJSIP aborts if our cipher list exceeds 1010 characters
+
+    // PJSIP aborts if our cipher list exceeds 1000 characters
     static const int MAX_CIPHERS_STRLEN = 1000;
 
     for (const auto &item : ciphers_) {
@@ -1031,12 +1116,15 @@ std::string SIPAccount::getContactHeader() const
 
     link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port);
 
-    if (!receivedParameter_.empty())
+    if (!receivedParameter_.empty()) {
         address = receivedParameter_;
+        DEBUG("Using received address %s", address.c_str());
+    }
 
-    if (rPort_ != -1) {
+    if (rPort_ != -1 and rPort_ != 0) {
         portstr << rPort_;
         port = portstr.str();
+        DEBUG("Using received port %s", port.c_str());
     }
 
     // UDP does not require the transport specification
@@ -1316,24 +1404,39 @@ bool SIPAccount::matches(const std::string &userName, const std::string &server,
         return false;
 }
 
-namespace {
-    // returns even number in range [lower, upper]
-    unsigned int getRandomEvenNumber(const std::pair<unsigned, unsigned> &range)
-    {
-        const unsigned halfUpper = range.second * 0.5;
-        const unsigned halfLower = range.first * 0.5;
-        return 2 * (halfLower + rand() % (halfUpper - halfLower + 1));
-    }
+SIPPresence * SIPAccount::getPresence(){
+    return presence_;
+}
+
+// returns even number in range [lower, upper]
+uint16_t
+SIPAccount::getRandomEvenNumber(const std::pair<uint16_t, uint16_t> &range)
+{
+    const uint16_t halfUpper = range.second * 0.5;
+    const uint16_t halfLower = range.first * 0.5;
+    uint16_t result;
+    do {
+        result = 2 * (halfLower + rand() % (halfUpper - halfLower + 1));
+    } while (portsInUse_[result / 2]);
+
+    portsInUse_[result / 2] = true;
+    return result;
+}
+
+void
+SIPAccount::releasePort(uint16_t port)
+{
+    portsInUse_[port / 2] = false;
 }
 
-unsigned
+uint16_t
 SIPAccount::generateAudioPort() const
 {
     return getRandomEvenNumber(audioPortRange_);
 }
 
 #ifdef SFL_VIDEO
-unsigned
+uint16_t
 SIPAccount::generateVideoPort() const
 {
     return getRandomEvenNumber(videoPortRange_);
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index c4b3c520c77e9e22805c622397c5db2761a2e451..e88eb66cb49888e486e7449b760b8c1611a385b6 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -92,6 +92,12 @@ namespace Conf {
     const char *const STUN_ENABLED_KEY = "stunEnabled";
     const char *const STUN_SERVER_KEY = "stunServer";
     const char *const CRED_KEY = "credential";
+    const char *const AUDIO_PORT_MIN_KEY = "audioPortMin";
+    const char *const AUDIO_PORT_MAX_KEY = "audioPortMax";
+#ifdef SFL_VIDEO
+    const char *const VIDEO_PORT_MIN_KEY = "videoPortMin";
+    const char *const VIDEO_PORT_MAX_KEY = "videoPortMax";
+#endif
 }
 
 class SIPVoIPLink;
@@ -102,6 +108,8 @@ class SIPPresence;
  * @file sipaccount.h
  * @brief A SIP Account specify SIP specific functions and object = SIPCall/SIPVoIPLink)
  */
+enum {MAX_PORT = 65536};
+enum {HALF_MAX_PORT = MAX_PORT / 2};
 
 class SIPAccount : public Account {
     public:
@@ -129,6 +137,9 @@ class SIPAccount : public Account {
          */
         bool isIP2IP() const;
 
+        static void
+        releasePort(uint16_t port);
+
         /**
          * Serialize internal state of this account for configuration
          * @param YamlEmitter the configuration engine which generate the configuration file
@@ -526,8 +537,9 @@ class SIPAccount : public Account {
         SIPPresence * getPresence();
 
         unsigned generateAudioPort() const;
+        uint16_t generateAudioPort() const;
 #ifdef SFL_VIDEO
-        unsigned generateVideoPort() const;
+        uint16_t generateVideoPort() const;
 #endif
 
     private:
@@ -786,14 +798,17 @@ class SIPAccount : public Account {
         /*
          * Port range for audio RTP ports
          */
-        std::pair<unsigned, unsigned> audioPortRange_;
+        std::pair<uint16_t, uint16_t> audioPortRange_;
 
 #ifdef SFL_VIDEO
         /**
          * Port range for video RTP ports
          */
-        std::pair<unsigned, unsigned> videoPortRange_;
+        std::pair<uint16_t, uint16_t> videoPortRange_;
 #endif
+        static bool portsInUse_[HALF_MAX_PORT];
+        static uint16_t getRandomEvenNumber(const std::pair<uint16_t, uint16_t> &range);
+
 };
 
 #endif
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index 5a1b7a0eb992eb8f714506fd4b2eb4f78ee3c415..da2768662bed7932445f0e42292e367268eaffe4 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -32,6 +32,7 @@
  */
 
 #include "sipcall.h"
+#include "sip_utils.h"
 #include "logger.h" // for _debug
 #include "sdp.h"
 #include "manager.h"
@@ -55,6 +56,7 @@ SIPCall::SIPCall(const std::string& id, Call::CallType type,
 #endif
     , pool_(pj_pool_create(&caching_pool->factory, id.c_str(), INITIAL_SIZE, INCREMENT_SIZE, NULL))
     , local_sdp_(new Sdp(pool_))
+    , contactHeader_()
 {}
 
 SIPCall::~SIPCall()
@@ -63,6 +65,11 @@ SIPCall::~SIPCall()
     pj_pool_release(pool_);
 }
 
+void SIPCall::setContactHeader(const std::string &contact)
+{
+    contactHeader_ = contact;
+}
+
 void SIPCall::answer()
 {
     pjsip_tx_data *tdata;
@@ -73,6 +80,12 @@ void SIPCall::answer()
     if (pjsip_inv_answer(inv, PJSIP_SC_OK, NULL, !inv->neg ? local_sdp_->getLocalSdpSession() : NULL, &tdata) != PJ_SUCCESS)
         throw std::runtime_error("Could not init invite request answer (200 OK)");
 
+    // contactStr must stay in scope as long as tdata
+    if (not contactHeader_.empty()) {
+        DEBUG("Answering with contact header: %s", contactHeader_.c_str());
+        sip_utils::addContactHeader(contactHeader_, tdata);
+    }
+
     if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
         throw std::runtime_error("Could not send invite request answer (200 OK)");
 
diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h
index e97b6851c2892e00beb81a9c0932ec28e40a1f00..fa2f840b96f3e217e0089f64dd7d5d70439c74d5 100644
--- a/daemon/src/sip/sipcall.h
+++ b/daemon/src/sip/sipcall.h
@@ -108,6 +108,8 @@ class SIPCall : public Call {
          */
         pjsip_inv_session *inv;
 
+        void setContactHeader(const std::string &contact);
+
     private:
         // override of Call::getDetails
         std::map<std::string, std::string>
@@ -140,6 +142,8 @@ class SIPCall : public Call {
          * The SDP session
          */
         Sdp *local_sdp_;
+
+        std::string contactHeader_;
 };
 
 #endif // __SIPCALL_H__
diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index 85f7c19bf2cf3142d17916d97d4899594d16df50..8a7167eed66351da5b0c1d40f24d90c907bb3dc4 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -204,6 +204,12 @@ pj_status_t SipTransport::createStunResolver(pj_str_t serverName, pj_uint16_t po
     pj_stun_config_init(&stunCfg, &cp_->factory, 0,
             pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_));
 
+    pj_status_t status = pj_stun_config_check_valid(&stunCfg);
+    if (status != PJ_SUCCESS) {
+        ERROR("STUN config is not valid");
+        return status;
+    }
+
     static const pj_stun_sock_cb stun_sock_cb = {
         stun_sock_on_rx_data_cb,
         NULL,
@@ -211,7 +217,7 @@ pj_status_t SipTransport::createStunResolver(pj_str_t serverName, pj_uint16_t po
     };
 
     pj_stun_sock *stun_sock = NULL;
-    pj_status_t status = pj_stun_sock_create(&stunCfg,
+    status = pj_stun_sock_create(&stunCfg,
             stunResolverName.c_str(), pj_AF_INET(), &stun_sock_cb, NULL, NULL,
             &stun_sock);
 
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 1fd38cc484d5f5999045a76449d30b35291e0daa..afb21800250469d16488f5f4d147b3dd7305ac22 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -229,23 +229,14 @@ void updateSDPFromSTUN(SIPCall &call, SIPAccount &account, const SipTransport &t
         stunPorts.resize(4);
 
         account.setPublishedAddress(pj_inet_ntoa(stunPorts[0].sin_addr));
+        // published IP MUST be updated first, since RTCP depends on it
+        call.getLocalSDP()->setPublishedIP(account.getPublishedAddress());
         call.getLocalSDP()->updatePorts(stunPorts);
     } catch (const std::runtime_error &e) {
         ERROR("%s", e.what());
     }
 }
 
-void
-addContactHeader(const std::string &contactStr, pjsip_tx_data *tdata)
-{
-    pj_str_t pjContact = pj_str((char*) contactStr.c_str());
-
-    pjsip_contact_hdr *contact = pjsip_contact_hdr_create(tdata->pool);
-    contact->uri = pjsip_parse_uri(tdata->pool, pjContact.ptr,
-                                   pjContact.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
-    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) contact);
-}
-
 pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 {
 
@@ -357,7 +348,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     setCallMediaLocal(call, addrToUse);
 
-    call->getLocalSDP()->setLocalIP(addrSdp);
+    call->getLocalSDP()->setPublishedIP(addrSdp);
 
     call->getAudioRtp().initConfig();
     try {
@@ -482,7 +473,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
         // contactStr must stay in scope as long as tdata
         const std::string contactStr(account->getContactHeader());
-        addContactHeader(contactStr, tdata);
+        sip_utils::addContactHeader(contactStr, tdata);
 
         if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS) {
             ERROR("Could not send msg for invite");
@@ -959,7 +950,7 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
 
     // Building the local SDP offer
     Sdp *localSDP = call->getLocalSDP();
-    localSDP->setLocalIP(localAddress);
+    localSDP->setPublishedIP(localAddress);
     const bool created = localSDP->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
 
     if (not created or not SIPStartCall(call)) {
@@ -1028,7 +1019,7 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
     call->initRecFilename(toUrl);
 
     Sdp *localSDP = call->getLocalSDP();
-    localSDP->setLocalIP(addrSdp);
+    localSDP->setPublishedIP(addrSdp);
     const bool created = localSDP->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
 
     if (not created or not SIPStartCall(call)) {
@@ -1046,13 +1037,22 @@ SIPVoIPLink::answer(Call *call)
         return;
 
     SIPCall *sipCall = static_cast<SIPCall*>(call);
+    SIPAccount *account = Manager::instance().getSipAccount(sipCall->getAccountId());
+    if (!account) {
+        ERROR("Could not find account %s", sipCall->getAccountId().c_str());
+        return;
+    }
+
     if (!sipCall->inv->neg) {
         WARN("Negotiator is NULL, we've received an INVITE without an SDP");
-        pjmedia_sdp_session *dummy;
+        pjmedia_sdp_session *dummy = 0;
         sdp_create_offer_cb(sipCall->inv, &dummy);
+        if (account->isStunEnabled())
+            updateSDPFromSTUN(*sipCall, *account, SIPVoIPLink::instance()->sipTransport);
     }
 
-    call->answer();
+    sipCall->setContactHeader(account->getContactHeader());
+    sipCall->answer();
 }
 
 namespace {
@@ -1110,7 +1110,7 @@ SIPVoIPLink::hangup(const std::string& id, int reason)
 
     // contactStr must stay in scope as long as tdata
     const std::string contactStr(account->getContactHeader());
-    addContactHeader(contactStr, tdata);
+    sip_utils::addContactHeader(contactStr, tdata);
 
     if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS)
         return;
@@ -1821,7 +1821,7 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
     setCallMediaLocal(call, localAddress);
 
     Sdp *localSDP = call->getLocalSDP();
-    localSDP->setLocalIP(addrSdp);
+    localSDP->setPublishedIP(addrSdp);
     const bool created = localSDP->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
     if (created)
         *p_offer = localSDP->getLocalSdpSession();
@@ -2391,10 +2391,9 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
 #ifdef SFL_VIDEO
     if (call->getLocalVideoPort() == 0) {
         // https://projects.savoirfairelinux.com/issues/17498
-        unsigned int callLocalVideoPort;
-        do
-            callLocalVideoPort = account->generateVideoPort();
-        while (call->getLocalAudioPort() == callLocalVideoPort);
+        const unsigned int callLocalVideoPort = account->generateVideoPort();
+        // this should already be guaranteed by SIPAccount
+        assert(call->getLocalAudioPort() != callLocalVideoPort);
 
         call->setLocalVideoPort(callLocalVideoPort);
         call->getLocalSDP()->setLocalPublishedVideoPort(callLocalVideoPort);
diff --git a/daemon/src/video/shm_sink.cpp b/daemon/src/video/shm_sink.cpp
index ab3c4f5937a9727cd57663aaee712f0199a729b9..7ff67e2a6c6137719ecc5e50307ca347e50c146e 100644
--- a/daemon/src/video/shm_sink.cpp
+++ b/daemon/src/video/shm_sink.cpp
@@ -146,7 +146,7 @@ SHMSink::stop()
 bool
 SHMSink::resize_area(size_t desired_length)
 {
-    if (desired_length < shm_area_len_)
+    if (desired_length <= shm_area_len_)
         return true;
 
     shm_unlock();
diff --git a/daemon/src/video/video_rtp_session.cpp b/daemon/src/video/video_rtp_session.cpp
index a3f44ea2ab478c3a2b83778577b208513ede4221..e9cc9ad76ca0cdd86ef3fd07d4e018ec087b38d5 100644
--- a/daemon/src/video/video_rtp_session.cpp
+++ b/daemon/src/video/video_rtp_session.cpp
@@ -131,7 +131,7 @@ void VideoRtpSession::start(int localPort)
     try {
         socketPair_.reset(new SocketPair(txArgs_["destination"].c_str(), localPort));
     } catch (const std::runtime_error &e) {
-        ERROR("Socket creation failed: %s", e.what());
+        ERROR("Socket creation failed on port %d: %s", localPort, e.what());
         return;
     }
 
diff --git a/daemon/test/sdptest.cpp b/daemon/test/sdptest.cpp
index 6020471f802997ab038b195c2aedeef968ef1ff7..428df49f826904301f39fc44c6543a0d9693b349 100644
--- a/daemon/test/sdptest.cpp
+++ b/daemon/test/sdptest.cpp
@@ -141,7 +141,7 @@ void SDPTest::testInitialOfferFirstCodec()
 {
     std::cout << "------------ SDPTest::testInitialOfferFirstCodec --------------" << std::endl;
 
-    CPPUNIT_ASSERT(session_->getLocalIP().empty());
+    CPPUNIT_ASSERT(session_->getPublishedIP().empty());
     CPPUNIT_ASSERT(session_->getRemoteIP().empty());
 
     std::vector<int> codecSelection;
@@ -152,7 +152,7 @@ void SDPTest::testInitialOfferFirstCodec()
 
     std::vector<std::map<std::string, std::string> > videoCodecs(createVideoCodecs());
 
-    session_->setLocalIP(LOCALHOST);
+    session_->setPublishedIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
     session_->createOffer(codecSelection, videoCodecs);
@@ -165,7 +165,7 @@ void SDPTest::testInitialOfferFirstCodec()
 
     session_->setMediaTransportInfoFromRemoteSdp();
 
-    CPPUNIT_ASSERT(session_->getLocalIP() == LOCALHOST);
+    CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST);
     CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com");
 }
 
@@ -173,7 +173,7 @@ void SDPTest::testInitialAnswerFirstCodec()
 {
     std::cout << "------------ SDPTest::testInitialAnswerFirstCodec -------------" << std::endl;
 
-    CPPUNIT_ASSERT(session_->getLocalIP().empty());
+    CPPUNIT_ASSERT(session_->getPublishedIP().empty());
     CPPUNIT_ASSERT(session_->getRemoteIP().empty());
 
     std::vector<int> codecSelection;
@@ -185,7 +185,7 @@ void SDPTest::testInitialAnswerFirstCodec()
 
     pjmedia_sdp_parse(testPool_, (char*) sdp_offer1, strlen(sdp_offer1), &remoteOffer);
 
-    session_->setLocalIP(LOCALHOST);
+    session_->setPublishedIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
     session_->receiveOffer(remoteOffer, codecSelection, createVideoCodecs());
@@ -194,7 +194,7 @@ void SDPTest::testInitialAnswerFirstCodec()
 
     session_->setMediaTransportInfoFromRemoteSdp();
 
-    CPPUNIT_ASSERT(session_->getLocalIP() == LOCALHOST);
+    CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST);
     CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com");
 }
 
@@ -202,7 +202,7 @@ void SDPTest::testInitialOfferLastCodec()
 {
     std::cout << "------------ SDPTest::testInitialOfferLastCodec --------------------" << std::endl;
 
-    CPPUNIT_ASSERT(session_->getLocalIP().empty());
+    CPPUNIT_ASSERT(session_->getPublishedIP().empty());
     CPPUNIT_ASSERT(session_->getRemoteIP().empty());
 
     std::vector<int> codecSelection;
@@ -211,7 +211,7 @@ void SDPTest::testInitialOfferLastCodec()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-    session_->setLocalIP(LOCALHOST);
+    session_->setPublishedIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
     session_->createOffer(codecSelection, createVideoCodecs());
@@ -224,7 +224,7 @@ void SDPTest::testInitialOfferLastCodec()
 
     session_->setMediaTransportInfoFromRemoteSdp();
 
-    CPPUNIT_ASSERT(session_->getLocalIP() == LOCALHOST);
+    CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST);
     CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com");
 }
 
@@ -232,7 +232,7 @@ void SDPTest::testInitialAnswerLastCodec()
 {
     std::cout << "------------ SDPTest::testInitialAnswerLastCodec ------------" << std::endl;
 
-    CPPUNIT_ASSERT(session_->getLocalIP().empty());
+    CPPUNIT_ASSERT(session_->getPublishedIP().empty());
     CPPUNIT_ASSERT(session_->getRemoteIP().empty());
 
     std::vector<int> codecSelection;
@@ -244,7 +244,7 @@ void SDPTest::testInitialAnswerLastCodec()
 
     pjmedia_sdp_parse(testPool_, (char*)sdp_offer2, strlen(sdp_offer2), &remoteOffer);
 
-    session_->setLocalIP(LOCALHOST);
+    session_->setPublishedIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
     session_->receiveOffer(remoteOffer, codecSelection, createVideoCodecs());
@@ -253,7 +253,7 @@ void SDPTest::testInitialAnswerLastCodec()
 
     session_->setMediaTransportInfoFromRemoteSdp();
 
-    CPPUNIT_ASSERT(session_->getLocalIP() == LOCALHOST);
+    CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST);
     CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com");
 }
 
@@ -262,7 +262,7 @@ void SDPTest::testReinvite()
 {
     std::cout << "------------ SDPTest::testReinvite --------------------" << std::endl;
 
-    CPPUNIT_ASSERT(session_->getLocalIP().empty());
+    CPPUNIT_ASSERT(session_->getPublishedIP().empty());
     CPPUNIT_ASSERT(session_->getRemoteIP().empty());
 
     std::vector<int> codecSelection;
@@ -270,7 +270,7 @@ void SDPTest::testReinvite()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-    session_->setLocalIP(LOCALHOST);
+    session_->setPublishedIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
     std::vector<std::map<std::string, std::string> > videoCodecs(createVideoCodecs());
@@ -285,7 +285,7 @@ void SDPTest::testReinvite()
 
     session_->setMediaTransportInfoFromRemoteSdp();
 
-    CPPUNIT_ASSERT(session_->getLocalIP() == LOCALHOST);
+    CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST);
     CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com");
     std::vector<sfl::AudioCodec*> codecs;
     session_->getSessionAudioMedia(codecs);
diff --git a/gnome/po/LINGUAS b/gnome/po/LINGUAS
index e828f7e15dd6e88561f03a444d463ca26d9d5f56..0fbd7e4fa4c0dbc777940e477c4db02545a267b4 100644
--- a/gnome/po/LINGUAS
+++ b/gnome/po/LINGUAS
@@ -24,6 +24,7 @@ sv
 te
 tr
 uz
+vi
 zh_CN
 zh_HK
 zh_TW
diff --git a/gnome/po/vi.po b/gnome/po/vi.po
new file mode 100644
index 0000000000000000000000000000000000000000..9ac49a04ad82aaad7b66b28e7ee6fe6a96e19be2
--- /dev/null
+++ b/gnome/po/vi.po
@@ -0,0 +1,1315 @@
+# Vietnamese translation for sflphone
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the sflphone package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sflphone\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2013-06-12 16:32-0400\n"
+"PO-Revision-Date: 2013-08-15 18:57+0000\n"
+"Last-Translator: Tho Duy Nguyen <nguyenduytho@gmail.com>\n"
+"Language-Team: Vietnamese <vi@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-08-15 19:28+0000\n"
+"X-Generator: Launchpad (build 16723)\n"
+
+#: ../src/accountlist.c:155
+msgid "Registered"
+msgstr "Đã đăng ký"
+
+#: ../src/accountlist.c:157
+msgid "Not Registered"
+msgstr "Chưa đăng ký"
+
+#: ../src/accountlist.c:159
+msgid "Trying..."
+msgstr "Đang thử"
+
+#: ../src/accountlist.c:161 ../src/sflnotify.c:170 ../src/sflnotify.c:183
+#, c-format
+msgid "Error"
+msgstr "Lỗi"
+
+#: ../src/accountlist.c:163
+msgid "Authentication Failed"
+msgstr "Xác thực thất bại"
+
+#: ../src/accountlist.c:165
+msgid "Network unreachable"
+msgstr "Mạng không thể tiếp cận"
+
+#: ../src/accountlist.c:167
+msgid "Host unreachable"
+msgstr "Máy không thể tiếp cận"
+
+#: ../src/accountlist.c:169
+msgid "Service unavailable"
+msgstr "Dịch vụ không sẵn sàng"
+
+#: ../src/accountlist.c:171
+msgid "Not acceptable"
+msgstr "Không thích hợp"
+
+#: ../src/accountlist.c:173
+msgid "Stun server invalid"
+msgstr "Máy chủ Stun không xác định"
+
+#: ../src/accountlist.c:175
+msgid "Ready"
+msgstr "Sẵn sàng"
+
+#: ../src/accountlist.c:177
+msgid "Invalid"
+msgstr "Không hợp lệ"
+
+#: ../src/actions.c:136
+msgid "Using account"
+msgstr "Sử dụng tài khoản"
+
+#: ../src/actions.c:140
+#, c-format
+msgid "No registered accounts"
+msgstr "Tài khoản chưa được đăng ký"
+
+#: ../src/actions.c:500
+#, c-format
+msgid "Direct SIP call"
+msgstr "Gọi trực tiếp bằng SIP"
+
+#. less than 1 week
+#. less than 1 day
+#: ../src/callable_obj.c:306
+msgid "today at %R"
+msgstr "hôm nay lúc %R"
+
+#. less than 2 days
+#: ../src/callable_obj.c:309
+msgid "yesterday at %R"
+msgstr "hôm qua lúc %R"
+
+#. between 2 days and 1 week
+#: ../src/callable_obj.c:311
+msgid "%A at %R"
+msgstr "%A lúc %R"
+
+#. more than 1 week
+#: ../src/callable_obj.c:315
+msgid "%x at %R"
+msgstr "%x lúc %R"
+
+#: ../src/config/accountconfigdialog.c:218
+msgid "_Auto-answer calls"
+msgstr "Tự động trả lời cuộc gọi"
+
+#: ../src/config/accountconfigdialog.c:238
+msgid "Account Parameters"
+msgstr "Tham số tài khoản"
+
+#. alias field
+#: ../src/config/accountconfigdialog.c:247 ../src/config/assistant.c:305
+#: ../src/config/assistant.c:403
+msgid "_Alias"
+msgstr "Bí d_anh:"
+
+#: ../src/config/accountconfigdialog.c:258
+msgid "_Protocol"
+msgstr "_Phương thức"
+
+#. Should never come here, add debug message.
+#: ../src/config/accountconfigdialog.c:275
+msgid "Unknown"
+msgstr "Không rõ"
+
+#. server field
+#: ../src/config/accountconfigdialog.c:290 ../src/config/assistant.c:313
+#: ../src/config/assistant.c:411
+msgid "_Host name"
+msgstr "_Tên máy chủ"
+
+#. username field
+#: ../src/config/accountconfigdialog.c:300 ../src/config/assistant.c:321
+#: ../src/config/assistant.c:419
+msgid "_User name"
+msgstr "_Tên người dùng"
+
+#. password field
+#: ../src/config/accountconfigdialog.c:321 ../src/config/assistant.c:331
+#: ../src/config/assistant.c:428
+msgid "_Password"
+msgstr "Mật _khẩu"
+
+#: ../src/config/accountconfigdialog.c:340 ../src/config/assistant.c:340
+#: ../src/config/assistant.c:437
+msgid "Show password"
+msgstr "Hiển thị mật khẩu"
+
+#: ../src/config/accountconfigdialog.c:345
+msgid "_Proxy"
+msgstr "_Proxy"
+
+#. voicemail number field
+#: ../src/config/accountconfigdialog.c:355 ../src/config/assistant.c:345
+#: ../src/config/assistant.c:442
+msgid "_Voicemail number"
+msgstr "_Số hộp thư thoại"
+
+#: ../src/config/accountconfigdialog.c:366
+msgid "_User-agent"
+msgstr "_User-agent"
+
+#: ../src/config/accountconfigdialog.c:419
+msgid "Authentication"
+msgstr "Xác thực"
+
+#: ../src/config/accountconfigdialog.c:420
+msgid "Secret"
+msgstr "Bí mật"
+
+#: ../src/config/accountconfigdialog.c:669
+msgid "Credential"
+msgstr "Ủy nhiệm"
+
+#: ../src/config/accountconfigdialog.c:701
+msgid "Authentication name"
+msgstr "Tên xác thực"
+
+#: ../src/config/accountconfigdialog.c:712
+msgid "Password"
+msgstr "Mật khẩu"
+
+#: ../src/config/accountconfigdialog.c:764
+#: ../src/config/accountconfigdialog.c:1380
+msgid "Security"
+msgstr "Bảo mật"
+
+#: ../src/config/accountconfigdialog.c:780
+msgid "Use TLS transport(sips)"
+msgstr "Dùng giao thức TLS (SIPS)"
+
+#. ZRTP subsection
+#: ../src/config/accountconfigdialog.c:788
+msgid "SRTP key exchange"
+msgstr "Trao đổi mã SRTP"
+
+#: ../src/config/accountconfigdialog.c:794
+msgid "Disabled"
+msgstr "Tắt"
+
+#: ../src/config/accountconfigdialog.c:858
+msgid "Registration"
+msgstr "Đăng ký"
+
+#: ../src/config/accountconfigdialog.c:862
+msgid "Registration expire"
+msgstr "Đăng ký đã hết hạn"
+
+#: ../src/config/accountconfigdialog.c:885
+msgid "Network Interface"
+msgstr "Giao diện mạng"
+
+#: ../src/config/accountconfigdialog.c:895
+msgid "Local address"
+msgstr "Địa chỉ cục bộ"
+
+#. Local port widget
+#: ../src/config/accountconfigdialog.c:928
+msgid "Local port"
+msgstr "Cổng mạng cục bộ"
+
+#: ../src/config/accountconfigdialog.c:969
+#: ../src/config/accountconfigdialog.c:1004
+msgid "Published address"
+msgstr "Địa chỉ công cộng"
+
+#: ../src/config/accountconfigdialog.c:973
+msgid "Using STUN"
+msgstr "Sử dụng STUN"
+
+#: ../src/config/accountconfigdialog.c:980
+msgid "STUN server URL"
+msgstr "URL máy chủ STUN"
+
+#: ../src/config/accountconfigdialog.c:988
+msgid "Same as local parameters"
+msgstr "Giống như tham số cục bộ"
+
+#: ../src/config/accountconfigdialog.c:992
+msgid "Set published address and port:"
+msgstr "Thiết lập địa chỉ và cổng mạng công cộng"
+
+#: ../src/config/accountconfigdialog.c:1013
+msgid "Published port"
+msgstr "Cổng mạng công khai"
+
+#. Box for the audiocodecs
+#: ../src/config/accountconfigdialog.c:1076
+#: ../src/config/accountconfigdialog.c:1361
+#: ../src/config/preferencesdialog.c:418
+msgid "Audio"
+msgstr "Âm thanh"
+
+#: ../src/config/accountconfigdialog.c:1088
+msgid "DTMF"
+msgstr "DTMF"
+
+#: ../src/config/accountconfigdialog.c:1092
+msgid "RTP"
+msgstr "RTP"
+
+#: ../src/config/accountconfigdialog.c:1098
+msgid "SIP"
+msgstr "SIP"
+
+#: ../src/config/accountconfigdialog.c:1106
+msgid "Ringtones"
+msgstr "Nhạc chuông"
+
+#: ../src/config/accountconfigdialog.c:1109
+msgid "Choose a ringtone"
+msgstr "Chọn nhạc chuông"
+
+#: ../src/config/accountconfigdialog.c:1112
+msgid "_Enable ringtones"
+msgstr "_Bật nhạc chuông"
+
+#: ../src/config/accountconfigdialog.c:1125
+msgid "Audio Files"
+msgstr "Tệp âm thanh"
+
+#. Box for the videocodecs
+#: ../src/config/accountconfigdialog.c:1149
+#: ../src/config/accountconfigdialog.c:1367
+#: ../src/config/preferencesdialog.c:424
+msgid "Video"
+msgstr "Phim"
+
+#: ../src/config/accountconfigdialog.c:1166
+#, c-format
+msgid ""
+"This profile is used when you want to reach a remote peer simply by typing a "
+"sip URI such as <b>sip:remotepeer</b>. The settings you define here will "
+"also be used if no account can be matched to an incoming or outgoing call."
+msgstr ""
+"Cấu hình này được dùng khi bạn muốn gọi bằng cái gõ URI sip ví dụ như "
+"<b>sip:remotepeer</b>. Các thiết lập mà bạn định ra ở đây cũng được dùng nếu "
+"như không có tài khỏan tương ứng với các cuộc gọi đi và đến."
+
+#: ../src/config/accountconfigdialog.c:1334
+msgid "Account settings"
+msgstr "Các thiết lập tài khoản"
+
+#: ../src/config/accountconfigdialog.c:1355
+msgid "Basic"
+msgstr "Cơ bản"
+
+#: ../src/config/accountconfigdialog.c:1375
+msgid "Advanced"
+msgstr "Tiên tiến"
+
+#: ../src/config/accountconfigdialog.c:1385
+msgid "Network"
+msgstr "mạng"
+
+#: ../src/config/accountlistconfigdialog.c:487
+msgid "Protocol"
+msgstr "Giao thức"
+
+#: ../src/config/accountlistconfigdialog.c:497
+msgid "Status"
+msgstr "Trạng thái"
+
+#: ../src/config/accountlistconfigdialog.c:595
+#, c-format
+msgid "Server returned \"%s\" (%d)"
+msgstr "Máy chủ trả lời \"%s\" (%d)"
+
+#: ../src/config/accountlistconfigdialog.c:617
+msgid "Accounts"
+msgstr "Các tài khoản"
+
+#: ../src/config/accountlistconfigdialog.c:626
+msgid "Configured Accounts"
+msgstr "Các tài khoản đã thiết lập"
+
+#: ../src/config/accountlistconfigdialog.c:652
+msgid "You have no active account"
+msgstr "Bạn không có tài khoản có hiệu lực"
+
+#: ../src/config/addressbook-config.c:313
+#: ../src/config/preferencesdialog.c:412 ../src/config/shortcuts-config.c:117
+msgid "General"
+msgstr "General"
+
+#. PHOTO DISPLAY
+#: ../src/config/addressbook-config.c:317
+msgid "_Use Evolution address books"
+msgstr "_Sử dụng danh bạ của Evolution"
+
+#: ../src/config/addressbook-config.c:324
+msgid "Download limit :"
+msgstr "Giới hạn tải xuống"
+
+#: ../src/config/addressbook-config.c:332
+msgid "cards"
+msgstr "thẻ"
+
+#. PHOTO DISPLAY
+#: ../src/config/addressbook-config.c:337
+msgid "_Display contact photo if available"
+msgstr "_Hiển thị hình của liên lạc nếu có"
+
+#. Fields
+#: ../src/config/addressbook-config.c:344
+msgid "Fields from Evolution's address books"
+msgstr "Các trường từ danh bạ Evolution"
+
+#: ../src/config/addressbook-config.c:347
+msgid "_Work"
+msgstr "_Chạy"
+
+#: ../src/config/addressbook-config.c:353
+msgid "_Home"
+msgstr "_Thư mục chính"
+
+#: ../src/config/addressbook-config.c:359
+msgid "_Mobile"
+msgstr "_Mobile"
+
+#. Address Book
+#: ../src/config/addressbook-config.c:365
+msgid "Address Books"
+msgstr "Danh bạ"
+
+#: ../src/config/addressbook-config.c:369
+msgid "Select which Evolution address books to use"
+msgstr "Hãy chọn trong các danh bạ Evolution"
+
+#: ../src/config/addressbook-config.c:402 ../src/config/audioconf.c:538
+#: ../src/config/videoconf.c:492
+msgid "Name"
+msgstr "Tên:"
+
+#: ../src/config/assistant.c:76
+msgid "This assistant is now finished."
+msgstr "Sự hỗ trợ này kết thúc ở đây"
+
+#: ../src/config/assistant.c:79
+msgid ""
+"You can at any time check your registration state or modify your accounts "
+"parameters in the Options/Accounts window."
+msgstr ""
+"Bạn có thể kiểm tra tình trạng đăng ký hoặc thay đổi các tham số tài khoản "
+"trong cửa sổLựa chọn/Tài khoản"
+
+#: ../src/config/assistant.c:81
+msgid "Alias"
+msgstr "Bí danh"
+
+#: ../src/config/assistant.c:82
+msgid "Server"
+msgstr "Máy chủ"
+
+#: ../src/config/assistant.c:83
+msgid "Username"
+msgstr "Tên người dùng"
+
+#: ../src/config/assistant.c:84
+msgid "Security: "
+msgstr "Bảo mật "
+
+#: ../src/config/assistant.c:88
+msgid "SRTP/ZRTP draft-zimmermann"
+msgstr "SRTP/ZRTP draft-zimmermann"
+
+#: ../src/config/assistant.c:90
+msgid "None"
+msgstr "Không có"
+
+#: ../src/config/assistant.c:226
+msgid "SFLphone account creation wizard"
+msgstr "Trợ giúp tạo tài khoản SFLphone"
+
+#: ../src/config/assistant.c:251
+msgid "Welcome to the Account creation wizard of SFLphone!"
+msgstr "Chào mừng bạn đến với trợ giúp tạo tài khoản SFLphone"
+
+#: ../src/config/assistant.c:252
+msgid "This installation wizard will help you configure an account."
+msgstr "Sự trợ giúp bạn cấu hình một tài khoản"
+
+#: ../src/config/assistant.c:264
+msgid "VoIP Protocols"
+msgstr "Các giao thức VoIP"
+
+#: ../src/config/assistant.c:264
+msgid "Select an account type"
+msgstr "Hãy lựa chọn một kiểu tài khoản"
+
+#: ../src/config/assistant.c:266
+msgid "SIP (Session Initiation Protocol)"
+msgstr "SIP (Session Initiation Protocol)"
+
+#: ../src/config/assistant.c:268
+msgid "IAX2 (InterAsterix Exchange)"
+msgstr "IAX2 (InterAsterix Exchange)"
+
+#: ../src/config/assistant.c:280
+msgid "Account"
+msgstr "Tài khoản"
+
+#: ../src/config/assistant.c:280
+msgid "Please select one of the following options"
+msgstr "Hãy chọn một trong các lựa chọn sau"
+
+#: ../src/config/assistant.c:282
+msgid ""
+"Create a free SIP/IAX2 account on sflphone.org \n"
+"(For testing purpose only)"
+msgstr "Tạo một tài khoản SIP/IAX2 miễn phí tại sflphone.org"
+
+#: ../src/config/assistant.c:284
+msgid "Register an existing SIP or IAX2 account"
+msgstr "Nhập vào một tài khoản SIP hoặc IAX2 đã có"
+
+#: ../src/config/assistant.c:297
+msgid "SIP account settings"
+msgstr "Thiết lập tài khoản SIP"
+
+#: ../src/config/assistant.c:297 ../src/config/assistant.c:395
+msgid "Please fill the following information"
+msgstr "Hãy điền vào các thông tin sau"
+
+#. Security options
+#: ../src/config/assistant.c:353 ../src/config/assistant.c:382
+msgid "Secure communications with _ZRTP"
+msgstr "Bảo mật liên lạc với _ZRTP"
+
+#: ../src/config/assistant.c:366
+msgid "Optional email address"
+msgstr "Địa chỉ thư điện tử tùy chọn"
+
+#: ../src/config/assistant.c:366
+msgid "This email address will be used to send your voicemail messages."
+msgstr "Địa chỉ thư điện tử sau sẽ được dùng để gửi các tin thư thoại"
+
+#. email field
+#: ../src/config/assistant.c:374
+msgid "_Email address"
+msgstr "_Thư điện tử"
+
+#: ../src/config/assistant.c:395
+msgid "IAX2 account settings"
+msgstr "Thiết lập tài khoản IAX2"
+
+#: ../src/config/assistant.c:460
+msgid "Network Address Translation (NAT)"
+msgstr "Network Address Translation (NAT)"
+
+#: ../src/config/assistant.c:460
+msgid "You should probably enable this if you are behind a firewall."
+msgstr "Có thể bạn phải bật tính năng này nếu bạn ở sau tường lửa."
+
+#. enable
+#: ../src/config/assistant.c:469
+msgid "E_nable STUN"
+msgstr "_Bật STUN"
+
+#. server address
+#: ../src/config/assistant.c:476
+msgid "_STUN server"
+msgstr "Máy chủ _STUN"
+
+#: ../src/config/assistant.c:491
+msgid "Account Registration"
+msgstr "Đăng ký tài khoản"
+
+#: ../src/config/assistant.c:491
+msgid "Congratulations!"
+msgstr "Xin chúc mừng!"
+
+#: ../src/config/audioconf.c:543
+msgid "Frequency"
+msgstr "Tần số"
+
+#: ../src/config/audioconf.c:548
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: ../src/config/audioconf.c:591
+msgid "ALSA plugin"
+msgstr "ALSA plugin"
+
+#: ../src/config/audioconf.c:612 ../src/config/audioconf.c:693
+msgid "Output"
+msgstr "Đầu ra"
+
+#: ../src/config/audioconf.c:633 ../src/config/audioconf.c:715
+msgid "Input"
+msgstr "Đầu vào"
+
+#: ../src/config/audioconf.c:653 ../src/config/audioconf.c:735
+msgid "Ringtone"
+msgstr "Nhạc chuông"
+
+#: ../src/config/audioconf.c:852
+msgid "Sound Manager"
+msgstr "Trình quản lý âm thanh"
+
+#: ../src/config/audioconf.c:859
+msgid "_Pulseaudio"
+msgstr "_Pulseaudio"
+
+#. Box for the Pulse configuration
+#: ../src/config/audioconf.c:864
+msgid "Pulseaudio settings"
+msgstr "Thiết lập Pulseaudio"
+
+#: ../src/config/audioconf.c:868
+msgid "_ALSA"
+msgstr "_ALSA"
+
+#. Box for the ALSA configuration
+#: ../src/config/audioconf.c:874
+msgid "ALSA settings"
+msgstr "Thiết lập ALSA"
+
+#: ../src/config/audioconf.c:889
+msgid "Recordings"
+msgstr "Bản thu"
+
+#. label
+#: ../src/config/audioconf.c:893
+msgid "Destination folder"
+msgstr "Thư mục đích"
+
+#. folder chooser button
+#: ../src/config/audioconf.c:897
+msgid "Select a folder"
+msgstr "Chọn một thư mục"
+
+#: ../src/config/audioconf.c:908
+msgid "_Always recording"
+msgstr "_Luôn ghi âm"
+
+#. Box for the voice enhancement configuration
+#: ../src/config/audioconf.c:915
+msgid "Voice enhancement settings"
+msgstr "Các thiết lập cải thiện âm"
+
+#: ../src/config/audioconf.c:918
+msgid "_Noise Reduction"
+msgstr "_Giảm nhiễu"
+
+#: ../src/config/audioconf.c:932
+msgid "_Echo Cancellation"
+msgstr "Giảm _Echo"
+
+#: ../src/config/hooks-config.c:151
+msgid "URL Argument"
+msgstr "Tham số URL"
+
+#: ../src/config/hooks-config.c:160
+msgid "Trigger on specific _SIP header"
+msgstr "Bật khi có header đặc biệt _SIP"
+
+#: ../src/config/hooks-config.c:169
+msgid "Trigger on _IAX2 URL"
+msgstr "Bật khi có URL _IAX2"
+
+#: ../src/config/hooks-config.c:175
+msgid "Command to _run"
+msgstr "Chạy _lệnh"
+
+#: ../src/config/hooks-config.c:183
+msgid "Phone number rewriting"
+msgstr "Viết lại số điện thoại"
+
+#: ../src/config/hooks-config.c:187
+msgid "_Prefix dialed numbers with"
+msgstr "_Thêm vào trước số điện thoại"
+
+#: ../src/config/hooks-config.c:198
+msgid "Messaging"
+msgstr "Lời nhắn"
+
+#: ../src/config/hooks-config.c:202
+msgid "Open URL in"
+msgstr "Mở URL trong"
+
+#: ../src/config/preferencesdialog.c:179
+msgid "Desktop Notifications"
+msgstr "Thông báo trên desktop"
+
+#. Notification All
+#: ../src/config/preferencesdialog.c:183
+msgid "_Enable notifications"
+msgstr "_Bật thông báo"
+
+#. Window Behaviour frame
+#: ../src/config/preferencesdialog.c:189
+msgid "Window Behaviour"
+msgstr "Hành vi cửa sổ"
+
+#: ../src/config/preferencesdialog.c:196
+msgid "Bring SFLphone to foreground on incoming calls"
+msgstr "Đưa SFLphone lên trên nếu có cuộc gọi đến"
+
+#. System Tray option frame
+#: ../src/config/preferencesdialog.c:203
+msgid "System Tray Icon (Legacy)"
+msgstr "System Tray Icon (Legacy)"
+
+#: ../src/config/preferencesdialog.c:210
+msgid "Show SFLphone in the system tray"
+msgstr "Hiện SFLphone trong system tray"
+
+#: ../src/config/preferencesdialog.c:216
+msgid "_Popup main window on incoming call"
+msgstr "_Bật cửa sổ chính khi có cuộc gọi đến"
+
+#: ../src/config/preferencesdialog.c:221
+msgid "Ne_ver popup main window"
+msgstr "_Không bao giờ bật cửa sổ chính"
+
+#. HISTORY CONFIGURATION
+#: ../src/config/preferencesdialog.c:237
+msgid "Calls History"
+msgstr "Nhật ký cuộc gọi"
+
+#: ../src/config/preferencesdialog.c:241
+msgid "_Keep my history for at least"
+msgstr "_Hãy giữ lại lược sử ít nhất"
+
+#: ../src/config/preferencesdialog.c:254
+msgid "days"
+msgstr "ngày"
+
+#. INSTANT MESSAGING CONFIGURATION
+#: ../src/config/preferencesdialog.c:258
+msgid "Instant Messaging"
+msgstr "Tin nhắn tức thời"
+
+#: ../src/config/preferencesdialog.c:262
+msgid "Enable instant messaging"
+msgstr "Bật tin nhắn tức thời"
+
+#: ../src/config/preferencesdialog.c:373
+msgid "Preferences"
+msgstr "Tùy chọn"
+
+#: ../src/config/preferencesdialog.c:430
+msgid "Hooks"
+msgstr "Hooks"
+
+#: ../src/config/preferencesdialog.c:435
+msgid "Shortcuts"
+msgstr "Đường tắt"
+
+#: ../src/config/preferencesdialog.c:441
+msgid "Address Book"
+msgstr "Sổ danh bạ"
+
+#: ../src/config/shortcuts-config.c:119
+msgid "Be careful: these shortcuts might override system-wide shortcuts."
+msgstr ""
+"Hãy cẩn thận: các đường tắt này sẽ thay đổi các đường tắt của hệ thống"
+
+#: ../src/config/tlsadvanceddialog.c:55
+msgid "Advanced options for TLS"
+msgstr "Các lựa chọn cao cấp cho TLS"
+
+#: ../src/config/tlsadvanceddialog.c:72
+msgid "TLS transport"
+msgstr "Giao thức TLS"
+
+#: ../src/config/tlsadvanceddialog.c:76
+#, c-format
+msgid ""
+"TLS transport can be used along with UDP for those calls that would\n"
+"require secure sip transactions (aka SIPS). You can configure a different\n"
+"TLS transport for each account. However, each of them will run on a "
+"dedicated\n"
+"port, different one from each other\n"
+msgstr ""
+"Giao thức TLS có để được sử dụng bên cạnh giao thức UDP cho các cuộc gọi\n"
+"cần mã hóa các trao đổi SIP (SIPS). Bạn có thể thiết lập giao thức TLS \n"
+"cho các tài khoản khác nhau. Tuy nhiên, mỗi tài khoản sẽ được chạy trên \n"
+"các cổng mạng khác nhau.\n"
+
+#: ../src/config/tlsadvanceddialog.c:120
+msgid "Global TLS listener (all accounts)"
+msgstr "Nghe TLS tổng quát (cho tất cả các tài khoản)"
+
+#: ../src/config/tlsadvanceddialog.c:130
+msgid "Certificate of Authority list"
+msgstr "Danh sách Certificate of Authority"
+
+#: ../src/config/tlsadvanceddialog.c:133
+msgid "Choose a CA list file (optional)"
+msgstr "Chọn một tệp danh sách CA (tùy ý)"
+
+#: ../src/config/tlsadvanceddialog.c:144
+msgid "Public endpoint certificate file"
+msgstr "Tệp Public endpoint certificate"
+
+#: ../src/config/tlsadvanceddialog.c:147
+msgid "Choose a public endpoint certificate (optional)"
+msgstr "Chọn một  public endpoint certificate (tùy ý)"
+
+#: ../src/config/tlsadvanceddialog.c:165
+msgid "Choose a private key file (optional)"
+msgstr "Chọn một tệp khóa cá nhân"
+
+#: ../src/config/tlsadvanceddialog.c:180
+msgid "Password for the private key"
+msgstr "Mật mã cho khóa cá nhân"
+
+#: ../src/config/tlsadvanceddialog.c:195
+msgid "TLS protocol method"
+msgstr "Phương pháp của giao thức TLS"
+
+#: ../src/config/tlsadvanceddialog.c:223
+msgid "TLS cipher list"
+msgstr "Danh sách mật mã TLS"
+
+#: ../src/config/tlsadvanceddialog.c:232
+msgid "Server name instance for outgoing TLS connection"
+msgstr "Tên của máy chủ cá biệt cho kết nối đi ra TLS"
+
+#: ../src/config/tlsadvanceddialog.c:240
+msgid "Negotiation timeout (sec:msec)"
+msgstr "Thời hạn cho sự dàn xếp (giây:micro giây)"
+
+#: ../src/config/tlsadvanceddialog.c:257
+msgid "Verify incoming certificates, as a server"
+msgstr "Kiểm tra các certificate mới đển, với phương diện máy chủ"
+
+#: ../src/config/tlsadvanceddialog.c:263
+msgid "Verify certificates from answer, as a client"
+msgstr "Kiểm tra các certificate trả lời, với phương diện máy khách"
+
+#: ../src/config/tlsadvanceddialog.c:269
+msgid "Require certificate for incoming tls connections"
+msgstr "Cần có certificate cho các kết nối đến TLS"
+
+#: ../src/config/videoconf.c:499
+msgid "Bitrate (kbps)"
+msgstr "Bitrate (kbps)"
+
+#: ../src/config/videoconf.c:506
+msgid "Parameters"
+msgstr "các tham số"
+
+#: ../src/config/videoconf.c:808
+msgid "No devices found"
+msgstr "Không tìm thấy thiết bị nào"
+
+#. Set choices of input devices
+#: ../src/config/videoconf.c:819
+msgid "Device"
+msgstr "Thiết Bị"
+
+#. Set choices of input
+#: ../src/config/videoconf.c:834
+msgid "Channel"
+msgstr "Kênh"
+
+#. Set choices of sizes
+#: ../src/config/videoconf.c:848
+msgid "Size"
+msgstr "Cỡ"
+
+#. Set choices of rates
+#: ../src/config/videoconf.c:862
+msgid "Rate"
+msgstr "Mức độ"
+
+#: ../src/config/videoconf.c:888
+msgid "Video Manager"
+msgstr "Trình quản lý Video"
+
+#: ../src/config/videoconf.c:891
+msgid "Video4Linux2"
+msgstr "Video4Linux2"
+
+#: ../src/config/videoconf.c:897
+msgid "Preview"
+msgstr "Xem thử"
+
+#: ../src/config/zrtpadvanceddialog.c:52
+msgid "ZRTP Options"
+msgstr "Lựa chọn ZRTP"
+
+#: ../src/config/zrtpadvanceddialog.c:69
+msgid "Send Hello Hash in S_DP"
+msgstr "Gửi Hello Hash trong S_DP"
+
+#: ../src/config/zrtpadvanceddialog.c:74
+msgid "Ask User to Confirm SAS"
+msgstr "Hỏi người dùng xác nhận SAS"
+
+#: ../src/config/zrtpadvanceddialog.c:79
+msgid "_Warn if ZRTP not supported"
+msgstr "_Cảnh báo nếu không hỗ trợ ZRTP"
+
+#: ../src/config/zrtpadvanceddialog.c:84
+msgid "Display SAS once for hold events"
+msgstr "Hiển thị SAS khi có sự kiện đang chờ"
+
+#: ../src/config/zrtpadvanceddialog.c:118
+msgid "SDES Options"
+msgstr "Lựa chọn SDES"
+
+#: ../src/config/zrtpadvanceddialog.c:134
+msgid "Fallback on RTP on SDES failure"
+msgstr "Quay về RTP nếu không sử dụng được SDES"
+
+#: ../src/contacts/searchbar.c:226
+msgid "Search all"
+msgstr "Tìm tất cả"
+
+#: ../src/contacts/searchbar.c:227 ../src/contacts/searchbar.c:235
+#: ../src/contacts/searchbar.c:243 ../src/contacts/searchbar.c:251
+msgid "Click here to change the search type"
+msgstr "Nhấn vào đây để sửa đổi kiểu tìm kiếm"
+
+#: ../src/contacts/searchbar.c:234
+msgid "Search by missed call"
+msgstr "Tìm các cuộc gọi nhỡ"
+
+#: ../src/contacts/searchbar.c:242
+msgid "Search by incoming call"
+msgstr "Tìm các cuộc gọi đến"
+
+#: ../src/contacts/searchbar.c:250
+msgid "Search by outgoing call"
+msgstr "Tìm các cuộc gọi đi"
+
+#: ../src/dbus/dbus.c:575
+msgid "ALSA notification: Error while opening playback device"
+msgstr "Thông báo ALSA: Lỗi khi mở thiết bị đọc"
+
+#: ../src/dbus/dbus.c:578
+msgid "ALSA notification: Error while opening capture device"
+msgstr "Thông báo ALSA: Lỗi khi mở thiết bị ghi"
+
+#: ../src/dbus/dbus.c:581
+msgid "Pulseaudio notification: Pulseaudio is not running"
+msgstr "Thông báo Pulseaudio: Hiện thời Pulseaudio đang bị tắt"
+
+#: ../src/dbus/dbus.c:584
+msgid "Codecs notification: Codecs not found"
+msgstr "Thông báo Codecs: không tìm thấy Codecs"
+
+#: ../src/mainwindow.c:138
+msgid "There is one call in progress."
+msgstr "Đang thực hiện một cuộc gọi"
+
+#: ../src/mainwindow.c:140
+msgid "There are calls in progress."
+msgstr "Đang thực hiện các cuộc gọi"
+
+#: ../src/mainwindow.c:145
+msgid "Do you still want to quit?"
+msgstr "Bạn vẫn muốn thoát ra?"
+
+#: ../src/mainwindow.c:494
+#, c-format
+msgid "ZRTP is not supported by peer %s\n"
+msgstr "Kết nối không hỗ trợ ZRTP %s\n"
+
+#: ../src/mainwindow.c:496
+msgid "Secure Communication Unavailable"
+msgstr "Không tồn tại liên lạc an toàn"
+
+#: ../src/mainwindow.c:499 ../src/mainwindow.c:525
+msgid "Continue"
+msgstr "Tiếp"
+
+#: ../src/mainwindow.c:500 ../src/mainwindow.c:526 ../src/mainwindow.c:543
+msgid "Stop Call"
+msgstr "Ngưng cuộc gọi"
+
+#: ../src/mainwindow.c:518
+#, c-format
+msgid ""
+"A %s error forced the call with %s to fall under unencrypted mode.\n"
+"Exact reason: %s\n"
+msgstr ""
+"Lỗi %s bắt buộc cuộc gọi với %s chuyển về phương thức không mã hóa.\n"
+"Lý do chính xác: %s\n"
+
+#: ../src/mainwindow.c:522
+msgid "ZRTP negotiation failed"
+msgstr "Dàn xếp ZRTP thất bại"
+
+#: ../src/mainwindow.c:536
+#, c-format
+msgid ""
+"%s wants to stop using secure communication. Confirm will resume "
+"conversation without SRTP.\n"
+msgstr ""
+"%s muốn ngưng sử dụng liên lạc an toàn. Hãy xác nhận việc tiếp tục đàm thoại "
+"với SRTP\n"
+
+#: ../src/mainwindow.c:538
+msgid "Confirm Go Clear"
+msgstr "Xác nhận Go Clear"
+
+#: ../src/mainwindow.c:541
+msgid "Confirm"
+msgstr "Xác nhận"
+
+#: ../src/sflphone_client.c:53
+#, c-format
+msgid ""
+"%s\n"
+"Run '%s --help' to see a full list of available command line options.\n"
+msgstr ""
+"%s\n"
+"Chạy '%s --help' để xem danh sách tuỳ chọn dòng lệnh.\n"
+
+#: ../src/sflphone_client.c:70
+msgid "SFLphone Error"
+msgstr "Lỗi SFLphone"
+
+#: ../src/sflphone_options.c:60
+msgid "Enable debug"
+msgstr "Bật gỡ lỗi"
+
+#: ../src/sflphone_options.c:67
+msgid "- GNOME client for SFLPhone"
+msgstr "- Chương trình khách GNOME cho SFLphone"
+
+#: ../src/sflnotify.c:93
+#, c-format
+msgid "%s says:"
+msgstr "%s báo:"
+
+#. the account is different from NULL
+#: ../src/sflnotify.c:115 ../src/sflnotify.c:135
+#, c-format
+msgid "%s account : %s"
+msgstr "Tài khoản %s: %s"
+
+#: ../src/sflnotify.c:120
+#, c-format
+msgid "<i>From</i> %s"
+msgstr "<i>Từ</i> %s"
+
+#. the account is different from NULL
+#: ../src/sflnotify.c:153
+#, c-format
+msgid "Calling with %s account <i>%s</i>"
+msgstr "Gọi với tài khoản %s <i>%s</i>"
+
+#: ../src/sflnotify.c:157
+#, c-format
+msgid "Current account"
+msgstr "Tài khoản hiện tại"
+
+#: ../src/sflnotify.c:169
+#, c-format
+msgid "You have no accounts set up"
+msgstr "Bạn không có tài khoàn nào được thiết lập"
+
+#: ../src/sflnotify.c:182
+#, c-format
+msgid "You have no registered accounts"
+msgstr "Bạn không có tài khoản nào được đăng ký"
+
+#: ../src/sflnotify.c:196
+#, c-format
+msgid ""
+"<i>With:</i> %s \n"
+"using %s"
+msgstr ""
+"<i>Với:</i> %s \n"
+"dùng %s"
+
+#: ../src/sflnotify.c:210
+#, c-format
+msgid "%s does not support ZRTP."
+msgstr "%s không hỗ trợ ZRTP"
+
+#: ../src/sflnotify.c:224
+#, c-format
+msgid "ZRTP negotiation failed with %s"
+msgstr "Dàn xếp ZRTP thất bại với %s"
+
+#: ../src/sflnotify.c:238
+#, c-format
+msgid "<i>With:</i> %s"
+msgstr "<i>Với:</i> %s"
+
+#: ../src/sliders.c:231
+msgid "Speakers volume"
+msgstr "Âm lượng"
+
+#: ../src/sliders.c:231
+msgid "Mic volume"
+msgstr "Âm lượng cho micro"
+
+#: ../src/statusicon.c:132
+msgid "_Show main window"
+msgstr "_Hiển thị cửa sổ chính"
+
+#: ../src/statusicon.c:139 ../src/uimanager.c:994 ../src/uimanager.c:1366
+#: ../src/uimanager.c:1435
+msgid "_Hang up"
+msgstr "_Ngừng"
+
+#: ../src/statusicon.c:190
+msgid "SFLphone"
+msgstr "SFLphone"
+
+#: ../src/uimanager.c:436
+msgid "No address book selected"
+msgstr "Chưa có sổ danh bạ nào được lựa chọn"
+
+#: ../src/uimanager.c:456 ../src/uimanager.c:1123
+msgid "Address book"
+msgstr "Sổ danh bạ"
+
+#: ../src/uimanager.c:483
+#, c-format
+msgid "Voicemail(%i)"
+msgstr "Thư thoại(%i)"
+
+#: ../src/uimanager.c:563
+msgid "SFLphone is a VoIP client compatible with SIP and IAX2 protocols."
+msgstr ""
+"SFLphone là một chương trình khách VoIP tương thích với các giao thức SIP và "
+"IAX2"
+
+#: ../src/uimanager.c:566
+msgid "About SFLphone"
+msgstr "Nói về SFLphone"
+
+#: ../src/uimanager.c:935 ../src/uimanager.c:1014
+msgid "Voicemail"
+msgstr "Thư thoại"
+
+#. Call Menu
+#: ../src/uimanager.c:984
+msgid "Call"
+msgstr "Gọi"
+
+#: ../src/uimanager.c:986 ../src/uimanager.c:1531
+msgid "_New call"
+msgstr "Cuộc gọi _mới"
+
+#: ../src/uimanager.c:987
+msgid "Place a new call"
+msgstr "Gọi mới"
+
+#: ../src/uimanager.c:990 ../src/uimanager.c:1355
+msgid "_Pick up"
+msgstr "_Nhấc máy"
+
+#: ../src/uimanager.c:991
+msgid "Answer the call"
+msgstr "Trả lời cuộc gọi"
+
+#: ../src/uimanager.c:995
+msgid "Finish the call"
+msgstr "Kết thúc cuộc gọi"
+
+#: ../src/uimanager.c:998
+msgid "O_n hold"
+msgstr "_Chờ"
+
+#: ../src/uimanager.c:999
+msgid "Place the call on hold"
+msgstr "Chuyển cuộc gọi sang chờ"
+
+#: ../src/uimanager.c:1002
+msgid "O_ff hold"
+msgstr "_Hết chờ"
+
+#: ../src/uimanager.c:1003
+msgid "Place the call off hold"
+msgstr "Chuyển cuộc gọi sang không chờ"
+
+#: ../src/uimanager.c:1006 ../src/uimanager.c:1420
+msgid "Send _message"
+msgstr "Gửi _thông điệp"
+
+#: ../src/uimanager.c:1007
+msgid "Send message"
+msgstr "Gửi thông điệp"
+
+#: ../src/uimanager.c:1010
+msgid "Configuration _Assistant"
+msgstr "Trợ lý cấu hình"
+
+#: ../src/uimanager.c:1011
+msgid "Run the configuration assistant"
+msgstr "Chạy Trợ lý Cấu hình"
+
+#: ../src/uimanager.c:1015
+msgid "Call your voicemail"
+msgstr "Gọi hộp thư thoại của bạn"
+
+#: ../src/uimanager.c:1018
+msgid "_Close"
+msgstr "Đón_g"
+
+#: ../src/uimanager.c:1019
+msgid "Minimize to system tray"
+msgstr "Thu nhỏ về khay hệ thống"
+
+#: ../src/uimanager.c:1022
+msgid "_Quit"
+msgstr "_Thoát"
+
+#: ../src/uimanager.c:1023
+msgid "Quit the program"
+msgstr "Thoát khỏi chương trình"
+
+#. Edit Menu
+#: ../src/uimanager.c:1027
+msgid "_Edit"
+msgstr "_Sửa"
+
+#: ../src/uimanager.c:1029
+msgid "_Copy"
+msgstr "_Sao chép"
+
+#: ../src/uimanager.c:1030
+msgid "Copy the selection"
+msgstr "Sao chép vùng chọn"
+
+#: ../src/uimanager.c:1033
+msgid "_Paste"
+msgstr "Riêng"
+
+#: ../src/uimanager.c:1034
+msgid "Paste the clipboard"
+msgstr "Dán bảng lưu tạm"
+
+#: ../src/uimanager.c:1037
+msgid "Clear _history"
+msgstr "_Xóa lược sử"
+
+#: ../src/uimanager.c:1038
+msgid "Clear the call history"
+msgstr "Xóa lược sử các cuộc gọi"
+
+#: ../src/uimanager.c:1041
+msgid "_Accounts"
+msgstr "Tài _khoản"
+
+#: ../src/uimanager.c:1042
+msgid "Edit your accounts"
+msgstr "Sửa đổi tài khoản của bạn"
+
+#: ../src/uimanager.c:1045
+msgid "_Preferences"
+msgstr "Tù_y thích"
+
+#: ../src/uimanager.c:1046
+msgid "Change your preferences"
+msgstr "Thay đổi sở thích của bạn"
+
+#. View Menu
+#: ../src/uimanager.c:1050
+msgid "_View"
+msgstr "_Xem"
+
+#. Help menu
+#: ../src/uimanager.c:1053
+msgid "_Help"
+msgstr "_Trợ giúp"
+
+#: ../src/uimanager.c:1054
+msgid "Contents"
+msgstr "Nội dung"
+
+#: ../src/uimanager.c:1055
+msgid "Open the manual"
+msgstr "Mở sổ tay hướng dẫn"
+
+#: ../src/uimanager.c:1057
+msgid "About this application"
+msgstr "Giới thiệu về ứng dụng này"
+
+#: ../src/uimanager.c:1116
+msgid "_Transfer"
+msgstr "_Chuyển"
+
+#: ../src/uimanager.c:1116
+msgid "Transfer the call"
+msgstr "Chuyển cuộc gọi"
+
+#: ../src/uimanager.c:1117 ../src/uimanager.c:1388
+msgid "_Record"
+msgstr "Th_u"
+
+#: ../src/uimanager.c:1117
+msgid "Record the current conversation"
+msgstr "Thu cuộc gọi hiện tại"
+
+#: ../src/uimanager.c:1118 ../src/uimanager.c:1400
+msgid "_Mute"
+msgstr "_Tắt"
+
+#: ../src/uimanager.c:1118
+msgid "Mute microphone for this call"
+msgstr "Tắt micro cho cuộc gọi này"
+
+#: ../src/uimanager.c:1119
+msgid "_Show toolbar"
+msgstr "_Hiện thanh công cụ"
+
+#: ../src/uimanager.c:1119
+msgid "Show the toolbar"
+msgstr "Hiện thanh công cụ"
+
+#: ../src/uimanager.c:1120
+msgid "_Dialpad"
+msgstr "Vùng _quay số"
+
+#: ../src/uimanager.c:1120
+msgid "Show the dialpad"
+msgstr "Hiện thị vùng quay số"
+
+#: ../src/uimanager.c:1121
+msgid "_Volume controls"
+msgstr "_Kiểm soát âm lượng"
+
+#: ../src/uimanager.c:1121
+msgid "Show the volume controls"
+msgstr "Hiển thị kiểm soát âm lượng"
+
+#: ../src/uimanager.c:1122
+msgid "_History"
+msgstr "_Lược sử"
+
+#: ../src/uimanager.c:1122
+msgid "Calls history"
+msgstr "Lược sử cuộc gọi"
+
+#: ../src/uimanager.c:1123
+msgid "_Address book"
+msgstr "_Danh bạ"
+
+#: ../src/uimanager.c:1377 ../src/uimanager.c:1444
+msgid "On _Hold"
+msgstr "Đang _chờ"
+
+#: ../src/uimanager.c:1481
+msgid "_Call back"
+msgstr "_Gọi lại"
+
+#: ../src/uimanager.c:1589
+msgid "Edit phone number"
+msgstr "Nhập số điện thoại"
+
+#: ../src/uimanager.c:1600
+msgid "Edit the phone number before making a call"
+msgstr "Nhập số điện thoại trước khi gọi"
diff --git a/gnome/src/account_schema.h b/gnome/src/account_schema.h
index 008c5776129a2760b96f870280e94cfaa926995f..5e72f5f39b6ca1d3eef84f770c8448d448f609f2 100644
--- a/gnome/src/account_schema.h
+++ b/gnome/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";
@@ -57,6 +58,7 @@ static const char *const CONFIG_KEEP_ALIVE_ENABLED              = "Account.keepA
 
 
 static const char *const CONFIG_DEFAULT_REGISTRATION_EXPIRE     = "60";
+static const char *const CONFIG_DEFAULT_RINGTONE_ENABLED        = "true";
 
 static const char *const CONFIG_ACCOUNT_HOSTNAME                = "Account.hostname";
 static const char *const CONFIG_ACCOUNT_USERNAME                = "Account.username";
@@ -65,7 +67,10 @@ static const char *const CONFIG_ACCOUNT_PASSWORD                = "Account.passw
 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_ACCOUNT_AUDIO_PORT_MIN          = "Account.audioPortMin";
+static const char *const CONFIG_ACCOUNT_AUDIO_PORT_MAX          = "Account.audioPortMax";
+static const char *const CONFIG_ACCOUNT_VIDEO_PORT_MIN          = "Account.videoPortMin";
+static const char *const CONFIG_ACCOUNT_VIDEO_PORT_MAX          = "Account.videoPortMax";
 
 static const char *const CONFIG_LOCAL_INTERFACE                 = "Account.localInterface";
 static const char *const CONFIG_INTERFACE                       = "Account.interface";
diff --git a/gnome/src/config/accountconfigdialog.c b/gnome/src/config/accountconfigdialog.c
index c38e7a34bfe642150b48b0d6697f0a4f7668b838..6d6b973a6091a1029f42a4578e2153e39aa75c57 100644
--- a/gnome/src/config/accountconfigdialog.c
+++ b/gnome/src/config/accountconfigdialog.c
@@ -97,6 +97,12 @@ static GtkWidget *security_tab;
 static GtkWidget *advanced_tab;
 static GtkWidget *overrtp;
 static GtkWidget *ringtone_seekslider;
+static GtkWidget *audio_port_min_spin_box;
+static GtkWidget *audio_port_max_spin_box;
+#ifdef SFL_VIDEO
+static GtkWidget *video_port_min_spin_box;
+static GtkWidget *video_port_max_spin_box;
+#endif
 
 typedef struct OptionsData {
     account_t *account;
@@ -1029,6 +1035,40 @@ GtkWidget* create_published_address(const account_t *account)
     return frame;
 }
 
+static void
+add_port_spin_button(const account_t *account, GtkWidget *grid, GtkWidget **spin,
+                 const gchar *key, const gchar *label_text, int left, int top)
+{
+    gchar *value = NULL;
+
+    if (account)
+        value = account_lookup(account, key);
+
+    *spin = gtk_spin_button_new_with_range(1024, 65535, 1);
+    GtkWidget *label = gtk_label_new_with_mnemonic(label_text);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), *spin);
+    gtk_grid_attach(GTK_GRID(grid), label, left, top, 1, 1);
+    if (value)
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(*spin), g_ascii_strtod(value, NULL));
+    gtk_grid_attach(GTK_GRID(grid), *spin, left + 1, top, 1, 1);
+}
+
+static GtkWidget*
+create_port_ranges(const account_t *account, const gchar * title,
+                   GtkWidget **min, GtkWidget **max,
+                   const gchar *key_min, const gchar *key_max, int top)
+{
+    GtkWidget *grid, *frame;
+    gnome_main_section_new_with_grid(title, &frame, &grid);
+    gtk_container_set_border_width(GTK_CONTAINER(grid), 10);
+    gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
+
+    add_port_spin_button(account, grid, min, key_min, _("Min"), 0, top);
+    add_port_spin_button(account, grid, max, key_max, _("Max"), 2, top);
+
+    return frame;
+}
+
 GtkWidget* create_advanced_tab(const account_t *account)
 {
     // Build the advanced tab, to appear on the account configuration panel
@@ -1047,6 +1087,18 @@ GtkWidget* create_advanced_tab(const account_t *account)
     frame = create_published_address(account);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
+    frame = create_port_ranges(account, _("Audio RTP Port Range"),
+            &audio_port_min_spin_box, &audio_port_max_spin_box,
+            CONFIG_ACCOUNT_AUDIO_PORT_MIN, CONFIG_ACCOUNT_AUDIO_PORT_MAX, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
+
+#ifdef SFL_VIDEO
+    frame = create_port_ranges(account, _("Video RTP Port Range"),
+            &video_port_min_spin_box, &video_port_max_spin_box,
+            CONFIG_ACCOUNT_VIDEO_PORT_MIN, CONFIG_ACCOUNT_VIDEO_PORT_MAX, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
+#endif
+
     gtk_widget_show_all(vbox);
 
     use_stun_cb(use_stun_check_box, NULL);
@@ -1257,6 +1309,17 @@ static void update_account_from_basic_tab(account_t *account)
 
                 account_replace(account, CONFIG_PUBLISHED_ADDRESS, published_address);
             }
+
+            account_replace(account, CONFIG_ACCOUNT_AUDIO_PORT_MIN,
+                            gtk_entry_get_text(GTK_ENTRY(audio_port_min_spin_box)));
+            account_replace(account, CONFIG_ACCOUNT_AUDIO_PORT_MAX,
+                            gtk_entry_get_text(GTK_ENTRY(audio_port_max_spin_box)));
+#ifdef SFL_VIDEO
+            account_replace(account, CONFIG_ACCOUNT_VIDEO_PORT_MIN,
+                            gtk_entry_get_text(GTK_ENTRY(video_port_min_spin_box)));
+            account_replace(account, CONFIG_ACCOUNT_VIDEO_PORT_MAX,
+                            gtk_entry_get_text(GTK_ENTRY(video_port_max_spin_box)));
+#endif
         }
 
         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overrtp))) {
diff --git a/gnome/src/config/utils.c b/gnome/src/config/utils.c
index ec03d2d02acc4014b54796b0a33d5a9d8b4d2559..3d06c2899950df81ca5e595755eefb498492b4e7 100644
--- a/gnome/src/config/utils.c
+++ b/gnome/src/config/utils.c
@@ -31,7 +31,7 @@
 #include "utils.h"
 #include "sflphone_const.h"
 
-void gnome_main_section_new_with_grid(gchar *title, GtkWidget **frame, GtkWidget **grid)
+void gnome_main_section_new_with_grid(const gchar *title, GtkWidget **frame, GtkWidget **grid)
 {
     PangoAttrList *attrs = pango_attr_list_new();
     PangoAttribute *attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
diff --git a/gnome/src/config/utils.h b/gnome/src/config/utils.h
index 728d62532247deec20929c45d6d5147e2bbb7ae0..2da55ebd064cdf97222091e248a57d9ca2353c6f 100644
--- a/gnome/src/config/utils.h
+++ b/gnome/src/config/utils.h
@@ -34,7 +34,7 @@
 #include <gtk/gtk.h>
 
 GtkWidget *gnome_main_section_new(const gchar * const title);
-void gnome_main_section_new_with_grid(gchar *title, GtkWidget**, GtkWidget**);
+void gnome_main_section_new_with_grid(const gchar *title, GtkWidget**, GtkWidget**);
 GtkWidget *gnome_info_bar (gchar *message, GtkMessageType type);
 
 #endif // _UTILS_