diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.cpp b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
index 5ce37ce1f53c08fc342d4b60daff3beefc3173dd..4b4b3c5c0e1ad676e37e0e1dde0d30e0038184d9 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
@@ -43,9 +43,9 @@
 namespace sfl {
 
 AudioRtpFactory::AudioRtpFactory(SIPCall *ca) : rtpSession_(NULL),
-    audioRtpThreadMutex_(), srtpEnabled_(false),
-    keyExchangeProtocol_(Symmetric), helloHashEnabled_(false),
-    remoteContext_(NULL), localContext_(NULL), ca_(ca)
+    audioRtpThreadMutex_(), srtpEnabled_(false), helloHashEnabled_(false),
+    remoteContext_(NULL), localContext_(NULL), ca_(ca),
+    keyExchangeProtocol_(NONE)
 {}
 
 AudioRtpFactory::~AudioRtpFactory()
@@ -53,7 +53,7 @@ AudioRtpFactory::~AudioRtpFactory()
     delete rtpSession_;
 }
 
-void AudioRtpFactory::initAudioRtpConfig()
+void AudioRtpFactory::initConfig()
 {
     if (rtpSession_ != NULL)
         stop();
@@ -65,23 +65,23 @@ void AudioRtpFactory::initAudioRtpConfig()
     if (account) {
         srtpEnabled_ = account->getSrtpEnabled();
         std::string key(account->getSrtpKeyExchange());
-
-        if (key == "sdes")
-            keyExchangeProtocol_ = Sdes;
-        else if (key == "zrtp")
-            keyExchangeProtocol_ = Zrtp;
-        else
-            keyExchangeProtocol_ = Symmetric;
-
+        if (srtpEnabled_) {
+            if (key == "sdes")
+                keyExchangeProtocol_ = SDES;
+            else if (key == "zrtp")
+                keyExchangeProtocol_ = ZRTP;
+        } else {
+            keyExchangeProtocol_ = NONE;
+        }
         helloHashEnabled_ = account->getZrtpHelloHash();
     } else {
         srtpEnabled_ = false;
-        keyExchangeProtocol_ = Symmetric;
+        keyExchangeProtocol_ = NONE;
         helloHashEnabled_ = false;
     }
 }
 
-void AudioRtpFactory::initAudioSymmetricRtpSession()
+void AudioRtpFactory::initSession()
 {
     ost::MutexLock m(audioRtpThreadMutex_);
 
@@ -90,7 +90,7 @@ void AudioRtpFactory::initAudioSymmetricRtpSession()
 
         switch (keyExchangeProtocol_) {
 
-            case Zrtp:
+            case ZRTP:
                 rtpSession_ = new AudioZrtpSession(ca_, zidFilename);
                 // TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's
                 // not even available at that point.
@@ -98,7 +98,7 @@ void AudioRtpFactory::initAudioSymmetricRtpSession()
                     ca_->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(rtpSession_)->getHelloHash());
                 break;
 
-            case Sdes:
+            case SDES:
                 rtpSession_ = new AudioSrtpSession(ca_);
                 break;
 
@@ -114,12 +114,11 @@ void AudioRtpFactory::start(AudioCodec* audiocodec)
     if (rtpSession_ == NULL)
         throw AudioRtpFactoryException("AudioRtpFactory: Error: RTP session was null when trying to start audio thread");
 
-    if (rtpSession_->getAudioRtpType() == Sdes)
-        if (localContext_ and remoteContext_)
-            static_cast<AudioSrtpSession *>(rtpSession_)->restoreCryptoContext(localContext_, remoteContext_);
+    if (keyExchangeProtocol_ == SDES and localContext_ and remoteContext_)
+        static_cast<AudioSrtpSession *>(rtpSession_)->restoreCryptoContext(localContext_, remoteContext_);
 
     if (rtpSession_->startRtpThread(audiocodec) != 0)
-        throw AudioRtpFactoryException("AudioRtpFactory: Error: Failed to start AudioZrtpSession thread");
+        throw AudioRtpFactoryException("AudioRtpFactory: Error: Failed to start AudioRtpSession thread");
 }
 
 void AudioRtpFactory::stop()
@@ -129,7 +128,7 @@ void AudioRtpFactory::stop()
     if (rtpSession_ == NULL)
         return;
 
-    if (rtpSession_->getAudioRtpType() == Sdes) {
+    if (keyExchangeProtocol_ == SDES) {
         localContext_ = static_cast<AudioSrtpSession*>(rtpSession_)->localCryptoCtx_;
         remoteContext_ = static_cast<AudioSrtpSession*>(rtpSession_)->remoteCryptoCtx_;
     }
@@ -162,7 +161,7 @@ void AudioRtpFactory::updateDestinationIpAddress()
 
 sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
 {
-    if (rtpSession_->getAudioRtpType() == Zrtp)
+    if (keyExchangeProtocol_ == ZRTP)
         return static_cast<AudioZrtpSession *>(rtpSession_);
     else
         throw AudioRtpFactoryException("RTP: Error: rtpSession_ is NULL in getAudioZrtpSession");
@@ -170,15 +169,16 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
 
 void sfl::AudioRtpFactory::initLocalCryptoInfo()
 {
-    if (rtpSession_ && rtpSession_->getAudioRtpType() == Sdes) {
-        static_cast<AudioSrtpSession *>(rtpSession_)->initLocalCryptoInfo();
-        ca_->getLocalSDP()->setLocalSdpCrypto(static_cast<AudioSrtpSession *>(rtpSession_)->getLocalCryptoInfo());
+    if (rtpSession_ && keyExchangeProtocol_ == SDES) {
+        AudioSrtpSession *srtpSession = static_cast<AudioSrtpSession*>(rtpSession_);
+        srtpSession->initLocalCryptoInfo();
+        ca_->getLocalSDP()->setLocalSdpCrypto(srtpSession->getLocalCryptoInfo());
     }
 }
 
 void AudioRtpFactory::setRemoteCryptoInfo(sfl::SdesNegotiator& nego)
 {
-    if (rtpSession_ && rtpSession_->getAudioRtpType() == Sdes)
+    if (rtpSession_ and keyExchangeProtocol_ == SDES)
         static_cast<AudioSrtpSession *>(rtpSession_)->setRemoteCryptoInfo(nego);
     else
         throw AudioRtpFactoryException("RTP: Error: rtpSession_ is NULL in setRemoteCryptoInfo");
diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.h b/daemon/src/audio/audiortp/audio_rtp_factory.h
index 9e8ca514ceb67216b48bb6408de2f1eb88d0f89d..f39d6519d33f4895694fe27ecaffd8ad4a820ba1 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.h
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.h
@@ -62,15 +62,15 @@ class AudioRtpFactory {
         AudioRtpFactory(SIPCall *ca);
         ~AudioRtpFactory();
 
-        void initAudioRtpConfig();
+        void initConfig();
 
         /**
          * 	Lazy instantiation method. Create a new RTP session of a given
          * type according to the content of the configuration file.
          * @param ca A pointer on a SIP call
-         * @return A new AudioSymmetricRtpSession object
+         * @return A new AudioRtpSession object
          */
-        void initAudioSymmetricRtpSession();
+        void initSession();
 
         /**
          * Start the audio rtp thread of the type specified in the configuration
@@ -103,7 +103,7 @@ class AudioRtpFactory {
         void updateDestinationIpAddress();
 
         bool isSdesEnabled() const {
-            return srtpEnabled_ and keyExchangeProtocol_ == sfl::Sdes;
+            return srtpEnabled_ and keyExchangeProtocol_ == SDES;
         }
 
         /**
@@ -140,17 +140,14 @@ class AudioRtpFactory {
 
     private:
         NON_COPYABLE(AudioRtpFactory);
+        enum KeyExchangeProtocol { NONE, SDES, ZRTP };
         AudioRtpSession *rtpSession_;
         ost::Mutex audioRtpThreadMutex_;
 
-        // Field used when initializinga udio rtp session
+        // Field used when initializing audio rtp session
         // May be set manually or from config using initAudioRtpConfig
         bool srtpEnabled_;
 
-        // Field used when initializinga udio rtp session
-        // May be set manually or from config using initAudioRtpConfig
-        RtpMethod keyExchangeProtocol_;
-
         // Field used when initializinga udio rtp session
         // May be set manually or from config using initAudioRtpConfig
         bool helloHashEnabled_;
@@ -162,6 +159,7 @@ class AudioRtpFactory {
         ost::CryptoContext *localContext_;
 
         SIPCall *ca_;
+        KeyExchangeProtocol keyExchangeProtocol_;
 };
 }
 #endif // __AUDIO_RTP_FACTORY_H__
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.cpp b/daemon/src/audio/audiortp/audio_rtp_session.cpp
index 2a6bea42e7e2f404cbe47751b1a2c1e3fb857a22..0df3c691dae301ebd7118866453910a22e3f3f03 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_session.cpp
@@ -43,17 +43,16 @@
 #include "manager.h"
 
 namespace sfl {
-AudioRtpSession::AudioRtpSession(SIPCall * sipcall, RtpMethod type, ost::RTPDataQueue *queue, ost::Thread *thread) :
+AudioRtpSession::AudioRtpSession(SIPCall * sipcall, ost::RTPDataQueue *queue, ost::Thread *thread) :
     AudioRtpRecordHandler(sipcall)
     , ca_(sipcall)
-    , type_(type)
-    , remote_ip_()
-    , remote_port_(0)
     , timestamp_(0)
     , timestampIncrement_(0)
-    , timestampCount_(0)
-    , isStarted_(false)
     , queue_(queue)
+    , isStarted_(false)
+    , remote_ip_()
+    , remote_port_(0)
+    , timestampCount_(0)
     , thread_(thread)
 {
     assert(ca_);
@@ -96,26 +95,28 @@ void AudioRtpSession::setSessionMedia(AudioCodec *audioCodec)
     else
         timestampIncrement_ = frameSize;
 
-    DEBUG("AudioRptSession: Codec payload: %d", payloadType);
-    DEBUG("AudioSymmetricRtpSession: Codec sampling rate: %d", smplRate);
-    DEBUG("AudioSymmetricRtpSession: Codec frame size: %d", frameSize);
-    DEBUG("AudioSymmetricRtpSession: RTP timestamp increment: %d", timestampIncrement_);
+    DEBUG("AudioRtpSession: Codec payload: %d", payloadType);
+    DEBUG("AudioRtpSession: Codec sampling rate: %d", smplRate);
+    DEBUG("AudioRtpSession: Codec frame size: %d", frameSize);
+    DEBUG("AudioRtpSession: RTP timestamp increment: %d", timestampIncrement_);
 
     if (payloadType == g722PayloadType) {
-        DEBUG("AudioSymmetricRtpSession: Setting G722 payload format");
+        DEBUG("AudioRtpSession: Setting G722 payload format");
         queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, g722RtpClockRate));
     } else {
         if (dynamic) {
-            DEBUG("AudioSymmetricRtpSession: Setting dynamic payload format");
+            DEBUG("AudioRtpSession: Setting dynamic payload format");
             queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, smplRate));
         } else {
-            DEBUG("AudioSymmetricRtpSession: Setting static payload format");
+            DEBUG("AudioRtpSession: Setting static payload format");
             queue_->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) payloadType));
         }
     }
+}
 
-    if (type_ != Zrtp)
-        ca_->setRecordingSmplRate(getCodecSampleRate());
+void AudioRtpSession::incrementTimestampForDTMF()
+{
+    timestamp_ += timestampIncrement_;
 }
 
 void AudioRtpSession::sendDtmfEvent()
@@ -131,7 +132,7 @@ void AudioRtpSession::sendDtmfEvent()
 
     DEBUG("AudioRtpSession: Send RTP Dtmf (%d)", payload.event);
 
-    timestamp_ += (type_ == Zrtp) ? 160 : timestampIncrement_;
+    incrementTimestampForDTMF();
 
     // discard equivalent size of audio
     processDataEncode();
@@ -166,22 +167,18 @@ void AudioRtpSession::receiveSpeakerData()
 }
 
 
-
 void AudioRtpSession::sendMicData()
 {
     int compSize = processDataEncode();
 
     // if no data return
-    if (!compSize)
+    if (compSize == 0)
         return;
 
     // Increment timestamp for outgoing packet
     timestamp_ += timestampIncrement_;
 
-    if (type_ == Zrtp)
-        queue_->putData(timestamp_, getMicDataEncoded(), compSize);
-
-    // putData put the data on RTP queue, sendImmediate bypass this queue
+    // putData puts the data on RTP queue, sendImmediate bypass this queue
     queue_->sendImmediate(timestamp_, getMicDataEncoded(), compSize);
 }
 
@@ -238,7 +235,7 @@ int AudioRtpSession::startRtpThread(AudioCodec* audiocodec)
     if (isStarted_)
         return 0;
 
-    DEBUG("AudioSymmetricRtpSession: Starting main thread");
+    DEBUG("AudioRtpSession: Starting main thread");
 
     isStarted_ = true;
     setSessionTimeouts();
@@ -247,14 +244,7 @@ int AudioRtpSession::startRtpThread(AudioCodec* audiocodec)
     initNoiseSuppress();
 
     queue_->enableStack();
-    int ret = thread_->start();
-
-    if (type_ == Zrtp)
-        return ret;
-
-    AudioSymmetricRtpSession *self = dynamic_cast<AudioSymmetricRtpSession*>(this);
-    assert(self);
-    return self->startSymmetricRtpThread();
+    return thread_->start();
 }
 
 
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.h b/daemon/src/audio/audiortp/audio_rtp_session.h
index 4f8723b234f0897490cadd65faa237518d02bbfc..f52f6472ef4cadc3fa7364db3556cef6c76e97db 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.h
+++ b/daemon/src/audio/audiortp/audio_rtp_session.h
@@ -46,29 +46,18 @@ namespace sfl {
 
 class AudioCodec;
 
-// Possible kind of rtp session
-typedef enum RtpMethod {
-    Symmetric,
-    Zrtp,
-    Sdes
-} RtpMethod;
-
-
 class AudioRtpSession : public AudioRtpRecordHandler {
     public:
         /**
         * Constructor
         * @param sipcall The pointer on the SIP call
         */
-        AudioRtpSession(SIPCall* sipcall, RtpMethod type, ost::RTPDataQueue *queue, ost::Thread *thread);
+        AudioRtpSession(SIPCall* sipcall, ost::RTPDataQueue *queue, ost::Thread *thread);
         virtual ~AudioRtpSession();
 
-        RtpMethod getAudioRtpType() {
-            return type_;
-        }
         void updateSessionMedia(AudioCodec *audioCodec);
 
-        int startRtpThread(AudioCodec*);
+        virtual int startRtpThread(AudioCodec*);
 
         /**
          * Used mostly when receiving a reinvite
@@ -76,6 +65,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         void updateDestinationIpAddress();
 
     protected:
+        /**
+         * Set the audio codec for this RTP session
+         */
+        virtual void setSessionMedia(AudioCodec *codec) = 0;
+
 
         bool onRTPPacketRecv(ost::IncomingRTPPkt&);
 
@@ -90,19 +84,26 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         /**
          * Send encoded data to peer
          */
-        void sendMicData();
+        virtual void sendMicData();
 
         SIPCall *ca_;
 
-        RtpMethod type_;
-
-    private:
-        NON_COPYABLE(AudioRtpSession);
+        /**
+         * Timestamp for this session
+         */
+        int timestamp_;
 
         /**
-         * Set the audio codec for this RTP session
+         * Timestamp incrementation value based on codec period length (framesize)
+         * except for G722 which require a 8 kHz incrementation.
          */
-        void setSessionMedia(AudioCodec*);
+        int timestampIncrement_;
+
+        ost::RTPDataQueue *queue_;
+
+        bool isStarted_;
+    private:
+        NON_COPYABLE(AudioRtpSession);
 
         /**
          * Set RTP Sockets send/receive timeouts
@@ -119,6 +120,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
          */
         void receiveSpeakerData();
 
+        /**
+         * Increment timestamp for DTMF event
+         */
+        virtual void incrementTimestampForDTMF();
+
         // Main destination address for this rtp session.
         // Stored in case or reINVITE, which may require to forget
         // this destination and update a new one.
@@ -129,26 +135,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         // this destination and update a new one
         unsigned short remote_port_;
 
-        /**
-         * Timestamp for this session
-         */
-        int timestamp_;
-
-        /**
-         * Timestamp incrementation value based on codec period length (framesize)
-         * except for G722 which require a 8 kHz incrementation.
-         */
-        int timestampIncrement_;
-
         /**
          * Timestamp reset frequency specified in number of packet sent
          */
         short timestampCount_;
 
-        bool isStarted_;
-
-        ost::RTPDataQueue *queue_;
-
         ost::Thread *thread_;
 };
 
diff --git a/daemon/src/audio/audiortp/audio_srtp_session.cpp b/daemon/src/audio/audiortp/audio_srtp_session.cpp
index ed8a637fc07953ce9a04e3879bab053b62084f5a..60e173ba62a63da2528abd7b638a51f789885c52 100644
--- a/daemon/src/audio/audiortp/audio_srtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_srtp_session.cpp
@@ -59,14 +59,7 @@ AudioSrtpSession::AudioSrtpSession(SIPCall * sipcall) :
     remoteMasterSalt_(),
     remoteMasterSaltLength_(0),
     remoteOfferIsSet_(false)
-{
-    type_ = Sdes;
-}
-
-AudioSrtpSession::~AudioSrtpSession()
-{
-    DEBUG("AudioSrtp: Destroy audio srtp session");
-}
+{}
 
 void AudioSrtpSession::initLocalCryptoInfo()
 {
@@ -326,4 +319,5 @@ char* AudioSrtpSession::decodeBase64(unsigned char *input, int length)
 
     return buffer;
 }
+
 }
diff --git a/daemon/src/audio/audiortp/audio_srtp_session.h b/daemon/src/audio/audiortp/audio_srtp_session.h
index f641e8eaa55b21065e7efcee35eb87f3543f93eb..02429d7b193d63a8777f7dfc441bdb1130f2a200 100644
--- a/daemon/src/audio/audiortp/audio_srtp_session.h
+++ b/daemon/src/audio/audiortp/audio_srtp_session.h
@@ -75,8 +75,6 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
          */
         AudioSrtpSession(SIPCall * sipcall);
 
-        ~AudioSrtpSession();
-
         /**
          * Used to get sdp crypto header to be included in sdp session. This
          * method must be called befor setRemoteCryptoInfo in case of an
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
index cc5d9ba37e068ad94c070a739cde6d6079b5116d..5169ce97eb44be937033f2eb918b460e823c4d88 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
@@ -44,8 +44,7 @@ namespace sfl {
 AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall * sipcall) :
     ost::TimerPort()
     , ost::SymmetricRTPSession(ost::InetHostAddress(sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort())
-    , AudioRtpSession(sipcall, Symmetric, this, this)
-    , echoCanceller()
+    , AudioRtpSession(sipcall, this, this)
     , rtpThread_(new AudioRtpThread(this))
 {
     DEBUG("AudioSymmetricRtpSession: Setting new RTP session with destination %s:%d", ca_->getLocalIp().c_str(), ca_->getLocalAudioPort());
@@ -54,12 +53,14 @@ AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall * sipcall) :
 
 AudioSymmetricRtpSession::~AudioSymmetricRtpSession()
 {
-    rtpThread_->running = false;
+    rtpThread_->running_ = false;
     delete rtpThread_;
 }
 
-AudioSymmetricRtpSession::AudioRtpThread::AudioRtpThread(AudioSymmetricRtpSession *session) : running(true), rtpSession(session)
-{}
+AudioSymmetricRtpSession::AudioRtpThread::AudioRtpThread(AudioSymmetricRtpSession *session) : running_(true), rtpSession_(session)
+{
+    assert(rtpSession_);
+}
 
 void AudioSymmetricRtpSession::AudioRtpThread::run()
 {
@@ -69,12 +70,12 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
 
     DEBUG("AudioRtpThread: Entering Audio rtp thread main loop");
 
-    while (running) {
+    while (running_) {
         // Send session
-        if (rtpSession->DtmfPending())
-            rtpSession->sendDtmfEvent();
+        if (rtpSession_->DtmfPending())
+            rtpSession_->sendDtmfEvent();
         else
-            rtpSession->sendMicData();
+            rtpSession_->sendMicData();
 
         Thread::sleep(TimerPort::getTimer());
 
@@ -84,4 +85,20 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
     DEBUG("AudioRtpThread: Leaving audio rtp thread loop");
 }
 
+void AudioSymmetricRtpSession::setSessionMedia(AudioCodec *audioCodec)
+{
+    AudioRtpSession::setSessionMedia(audioCodec);
+    ca_->setRecordingSmplRate(getCodecSampleRate());
+}
+
+int AudioSymmetricRtpSession::startRtpThread(AudioCodec* audiocodec)
+{
+    DEBUG("AudioSymmetricRtpSession: Starting main thread");
+    if (isStarted_)
+        return 0;
+
+    AudioRtpSession::startRtpThread(audiocodec);
+    return startSymmetricRtpThread();
+}
+
 }
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
index 256e55ae69f53ab36f349dbd7bb478e4f311ffd7..96270012d262ecedeacbbf632a75a9160417f85a 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
@@ -47,7 +47,6 @@ using std::ptrdiff_t;
 #pragma GCC diagnostic ignored "-Weffc++"
 #include <ccrtp/rtp.h>
 #include <ccrtp/iqueue.h>
-#include <cc++/numbers.h> // ost::Time
 
 class SIPCall;
 
@@ -60,7 +59,6 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
         * @param sipcall The pointer on the SIP call
         */
         AudioSymmetricRtpSession(SIPCall* sipcall);
-
         ~AudioSymmetricRtpSession();
 
         virtual bool onRTPPacketRecv(ost::IncomingRTPPkt& pkt) {
@@ -68,7 +66,6 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
         }
 
         int startSymmetricRtpThread() {
-            assert(rtpThread_);
             return rtpThread_->start();
         }
 
@@ -78,19 +75,18 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
         class AudioRtpThread : public ost::Thread, public ost::TimerPort {
             public:
                 AudioRtpThread(AudioSymmetricRtpSession *session);
-                ~AudioRtpThread(){}
 
                 virtual void run();
 
-                bool running;
+                bool running_;
 
             private:
                 NON_COPYABLE(AudioRtpThread);
-                AudioSymmetricRtpSession *rtpSession;
+                AudioSymmetricRtpSession *rtpSession_;
         };
-        SpeexEchoCancel echoCanceller;
+        void setSessionMedia(AudioCodec *codec);
+        int startRtpThread(AudioCodec* audiocodec);
 
-    private:
         AudioRtpThread *rtpThread_;
 };
 
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.cpp b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
index ebdb8f839e421b1494341b8a19bf846f9c6218c2..81903a9aae11eb9b2a5878d68064b3d15419798e 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
@@ -50,7 +50,7 @@
 namespace sfl {
 
 AudioZrtpSession::AudioZrtpSession(SIPCall * sipcall, const std::string& zidFilename) :
-    AudioRtpSession(sipcall, Zrtp, this, this),
+    AudioRtpSession(sipcall, this, this),
     ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue>(ost::InetHostAddress(sipcall->getLocalIp().c_str()),
             sipcall->getLocalAudioPort(),
             0,
@@ -117,6 +117,24 @@ void AudioZrtpSession::initializeZid()
     return;
 }
 
+void AudioZrtpSession::sendMicData()
+{
+    int compSize = processDataEncode();
+
+    // if no data return
+    if (compSize == 0)
+        return;
+
+    // Increment timestamp for outgoing packet
+    timestamp_ += timestampIncrement_;
+
+    // this step is only needed for ZRTP
+    queue_->putData(timestamp_, getMicDataEncoded(), compSize);
+
+    // putData puts the data on RTP queue, sendImmediate bypasses this queue
+    queue_->sendImmediate(timestamp_, getMicDataEncoded(), compSize);
+}
+
 void AudioZrtpSession::run()
 {
     // Set recording sampling rate
@@ -165,4 +183,17 @@ void AudioZrtpSession::run()
 
     DEBUG("AudioZrtpSession: Left main loop for call %s", ca_->getCallId().c_str());
 }
+
+
+void AudioZrtpSession::incrementTimestampForDTMF()
+{
+    timestamp_ += 160;
+}
+
+
+void AudioZrtpSession::setSessionMedia(AudioCodec *audioCodec)
+{
+    AudioRtpSession::setSessionMedia(audioCodec);
+}
+
 }
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.h b/daemon/src/audio/audiortp/audio_zrtp_session.h
index 3a19a5e3fd148e2e9090965a0b058bb56296407f..00d9dad819d875b9b8854bcaf2c164a5ea214e7d 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.h
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.h
@@ -43,6 +43,7 @@ using std::ptrdiff_t;
 #include <cc++/numbers.h> // OST::Time
 
 class SIPCall;
+class AudioCodec;
 
 namespace sfl {
 
@@ -68,8 +69,11 @@ class AudioZrtpSession : public AudioRtpSession, protected ost::Thread, public o
         }
 
     private:
+        void sendMicData();
         void initializeZid();
         std::string zidFilename_;
+        void incrementTimestampForDTMF();
+        void setSessionMedia(AudioCodec *codec);
 };
 
 }
diff --git a/daemon/src/sip/sdes_negotiator.h b/daemon/src/sip/sdes_negotiator.h
index 7fb4213555d670af6bd32f68073584107a886c09..416f940b011eecd97d00e196a44e07cb146e688f 100644
--- a/daemon/src/sip/sdes_negotiator.h
+++ b/daemon/src/sip/sdes_negotiator.h
@@ -80,7 +80,7 @@ struct CryptoSuiteDefinition {
 * List of accepted Crypto-Suites
 * as defined in RFC4568 (6.2)
 */
-const CryptoSuiteDefinition CryptoSuites[3] = {
+static const CryptoSuiteDefinition CryptoSuites[] = {
     { (char*) "AES_CM_128_HMAC_SHA1_80", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 80, 80, 160, 160 },
     { (char*) "AES_CM_128_HMAC_SHA1_32", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 32, 80, 160, 160 },
     { (char*) "F8_128_HMAC_SHA1_80", 128, 112, 48, 31, AESF8Mode, 128, HMACSHA1, 80, 80, 160, 160 }
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index a6bf9c935e84cd10fa4b0b137d9a0f568f6eb34f..8a482f76fd7e1d5ecc75bf02cae0801e0240ad87 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -322,8 +322,8 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     call->getLocalSDP()->setLocalIP(addrSdp);
 
-    call->getAudioRtp().initAudioRtpConfig();
-    call->getAudioRtp().initAudioSymmetricRtpSession();
+    call->getAudioRtp().initConfig();
+    call->getAudioRtp().initSession();
 
     if (rdata->msg_info.msg->body) {
         char sdpbuffer[1000];
@@ -340,7 +340,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
             CryptoOffer crypto_offer;
             crypto_offer.push_back(std::string(sdpoffer.substr(start, (sdpoffer.size() - start) - 1)));
 
-            std::vector<sfl::CryptoSuiteDefinition>localCapabilities;
+            std::vector<sfl::CryptoSuiteDefinition> localCapabilities;
 
             for (int i = 0; i < 3; i++)
                 localCapabilities.push_back(sfl::CryptoSuites[i]);
@@ -699,8 +699,8 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU
     }
 
     try {
-        call->getAudioRtp().initAudioRtpConfig();
-        call->getAudioRtp().initAudioSymmetricRtpSession();
+        call->getAudioRtp().initConfig();
+        call->getAudioRtp().initSession();
         call->getAudioRtp().initLocalCryptoInfo();
         call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
     } catch (...) {
@@ -834,8 +834,8 @@ SIPVoIPLink::offhold(const std::string& id)
         if (audiocodec == NULL)
             throw VoipLinkException("Could not instantiate codec");
 
-        call->getAudioRtp().initAudioRtpConfig();
-        call->getAudioRtp().initAudioSymmetricRtpSession();
+        call->getAudioRtp().initConfig();
+        call->getAudioRtp().initSession();
         call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
     } catch (const SdpException &e) {
         ERROR("UserAgent: Exception: %s", e.what());
@@ -1168,8 +1168,8 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
 
     // Audio Rtp Session must be initialized before creating initial offer in SDP session
     // since SDES require crypto attribute.
-    call->getAudioRtp().initAudioRtpConfig();
-    call->getAudioRtp().initAudioSymmetricRtpSession();
+    call->getAudioRtp().initConfig();
+    call->getAudioRtp().initSession();
     call->getAudioRtp().initLocalCryptoInfo();
     call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
 
@@ -1416,7 +1416,7 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
         std::string accountID = Manager::instance().getAccountFromCall(call->getCallId());
 
         if (dynamic_cast<SIPAccount*>(Manager::instance().getAccount(accountID))->getSrtpFallback())
-            call->getAudioRtp().initAudioSymmetricRtpSession();
+            call->getAudioRtp().initSession();
     }
 
     if (!sdpSession)