diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp
index cc52b96c636d36546c82c6c916b9a7decdc189e5..8c8d54d1db3a378b29803f0595293073f0e5a575 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp
+++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp
@@ -127,7 +127,7 @@ void AudioRtpFactory::initAudioRtpSession (SIPCall * ca)
                 if (_helloHashEnabled) {
                     // TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's
                     // not even available at that point.
-                    ca->getLocalSDP()->set_zrtp_hash (static_cast<AudioZrtpSession *> (_rtpSession)->getHelloHash());
+                    ca->getLocalSDP()->setZrtpHash (static_cast<AudioZrtpSession *> (_rtpSession)->getHelloHash());
                     _debug ("AudioRtpFactory: Zrtp hello hash fed to SDP");
                 }
 
@@ -320,7 +320,7 @@ void sfl::AudioRtpFactory::initLocalCryptoInfo (SIPCall * ca)
     if (_rtpSession && _rtpSessionType && (_rtpSessionType == Sdes)) {
         static_cast<AudioSrtpSession *> (_rtpSession)->initLocalCryptoInfo ();
 
-        ca->getLocalSDP()->set_srtp_crypto (static_cast<AudioSrtpSession *> (_rtpSession)->getLocalCryptoInfo());
+        ca->getLocalSDP()->setLocalSdpCrypto (static_cast<AudioSrtpSession *> (_rtpSession)->getLocalCryptoInfo());
     }
 }
 
diff --git a/sflphone-common/src/sip/sdp.cpp b/sflphone-common/src/sip/sdp.cpp
index b921c47e2d500df55689d9e6a67867151ba0a936..5a5d62532b9518da8120389416cbcbcead9c602d 100644
--- a/sflphone-common/src/sip/sdp.cpp
+++ b/sflphone-common/src/sip/sdp.cpp
@@ -717,6 +717,21 @@ void Sdp::setPortToAllMedia (int port)
     }
 }
 
+void Sdp::addAttributeToLocalAudioMedia(std::string attr)
+{
+    pjmedia_sdp_attr *attribute;
+
+    attribute = pjmedia_sdp_attr_create (memPool, attr.c_str(), NULL);
+
+	pjmedia_sdp_media_add_attr (getLocalSdpSession()->media[0], attribute);
+}
+
+void Sdp::removeAttributeFromLocalAudioMedia(std::string attr)
+{
+	pjmedia_sdp_media_remove_all_attr (getLocalSdpSession()->media[0], attr.c_str());
+
+}
+
 std::string Sdp::convertIntToString (int value)
 {
     std::ostringstream result;
diff --git a/sflphone-common/src/sip/sdp.h b/sflphone-common/src/sip/sdp.h
index e44fcf5fa333607adb783d0e99da6c9e610b1ff8..73ccecb185ec61307ed7d07d6fa49f71a0c4b4b1 100644
--- a/sflphone-common/src/sip/sdp.h
+++ b/sflphone-common/src/sip/sdp.h
@@ -282,30 +282,52 @@ class Sdp
             return remoteAudioPort;
         }
 
-        std::vector<sdpMedia*> getSessionMediaList (void) {
+        /**
+         * Get media list for this session
+         */
+        SdpMediaList getSessionMediaList (void) {
             return sessionAudioMedia;
         }
 
+        /**
+         *
+         */
+        void addAttributeToLocalAudioMedia(std::string);
+
+        /**
+         *
+         */
+        void removeAttributeFromLocalAudioMedia(std::string);
+
+
+        /**
+         * Get SRTP master key
+         * @param remote sdp session
+         * @param crypto offer
+         */
         void getRemoteSdpCryptoFromOffer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer);
 
+        /**
+         * Set the SRTP master_key
+         * @param mk The Master Key of a srtp session.
+         */
+        inline void setLocalSdpCrypto (const std::vector<std::string> lc) {
+            srtpCrypto = lc;
+        }
 
-        /* Set the zrtp hash that was previously calculated from the hello message in the zrtp layer.
+        /**
+         * Set the zrtp hash that was previously calculated from the hello message in the zrtp layer.
          * This hash value is unique at the media level. Therefore, if video support is added, one would
          * have to set the correct zrtp-hash value in the corresponding media section.
          * @param hash The hello hash of a rtp session. (Only audio at the moment)
          */
-        inline void set_zrtp_hash (const std::string& hash) {
+        inline void setZrtpHash (const std::string& hash) {
             zrtpHelloHash = hash;
-            _debug ("Zrtp hash set with %s\n", hash.c_str());
-        }
-
-        /* Set the srtp _master_key
-             * @param mk The Master Key of a srtp session.
-             */
-        inline void set_srtp_crypto (const std::vector<std::string> lc) {
-            srtpCrypto = lc;
         }
 
+        /**
+         * Print internal state info
+         */
         void toString (void);
 
 
diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp
index 87a501d4b8f611429b7b23487c336a0ecaef18fe..9302e9c9ef9ca59b29b1fa9f15c216dde99178d6 100644
--- a/sflphone-common/src/sip/sipvoiplink.cpp
+++ b/sflphone-common/src/sip/sipvoiplink.cpp
@@ -897,35 +897,109 @@ SIPVoIPLink::cancel (const CallID& id)
     return true;
 }
 
+
 bool
 SIPVoIPLink::onhold (const CallID& id)
 {
-
+	Sdp *sdpSession;
     pj_status_t status;
     SIPCall* call;
 
     call = getSIPCall (id);
 
-    if (call==0) {
-        _debug ("! SIP Error: call doesn't exist");
+    if (call == NULL) {
+        _debug ("UserAgent: Error: call doesn't exist in onhold action");
         return false;
     }
 
-
     // Stop sound
     call->setAudioStart (false);
-
     call->setState (Call::Hold);
+    call->getAudioRtp()->stop();
 
-    _debug ("* SIP Info: Stopping AudioRTP for onhold action");
+    _debug ("UserAgent: Stopping RTP session for on hold action");
 
-    call->getAudioRtp()->stop();
+    if ( (sdpSession = call->getLocalSDP()) == NULL) {
+        _debug ("UserAgent: Error: Unable to find local sdp");
+        return false;
+    }
+
+    sdpSession->removeAttributeFromLocalAudioMedia("sendrecv");
+    sdpSession->removeAttributeFromLocalAudioMedia("sendonly");
+
+    sdpSession->addAttributeToLocalAudioMedia("sendonly");
+
+    // Create re-INVITE with new offer
+    status = SIPSessionReinvite (call);
+
+    if (status != PJ_SUCCESS) {
+        return false;
+    }
+
+    return true;
+}
+
+bool
+SIPVoIPLink::offhold (const CallID& id)
+{
+	Sdp *sdpSession;
+    pj_status_t status;
+    SIPCall *call;
+
+    _debug ("UserAgent: retrive call from hold status");
+
+    call = getSIPCall (id);
+
+    if (call==0) {
+        _debug ("! SIP Error: Call doesn't exist");
+        return false;
+    }
+
+    if ( (sdpSession = call->getLocalSDP()) == NULL) {
+        _debug ("UserAgent: Error: Unable to find local sdp");
+        return false;
+    }
+
+    // Retreive previously selected codec
+    sfl::Codec *sessionMedia = sdpSession->getSessionMedia();
+
+    if (!sessionMedia) {
+        return false;
+    }
+
+    // Get PayloadType for this codec
+    AudioCodecType pl = (AudioCodecType) sessionMedia->getPayloadType();
+
+    _debug ("UserAgent: Payload from session media %d", pl);
+
+    try {
+        // Create a new instance for this codec
+        sfl::Codec* audiocodec = Manager::instance().getCodecDescriptorMap().instantiateCodec (pl);
+
+        if (audiocodec == NULL)
+            _error ("UserAgent: No audiocodec found");
+
+        call->getAudioRtp()->initAudioRtpConfig (call);
+        call->getAudioRtp()->initAudioRtpSession (call);
+        call->getAudioRtp()->start (static_cast<AudioCodec *>(audiocodec));
+
+    } catch (...) {
+        _debug ("! SIP Failure: Unable to create RTP Session (%s:%d)", __FILE__, __LINE__);
+    }
+
+    sdpSession->removeAttributeFromLocalAudioMedia("sendrecv");
+    sdpSession->removeAttributeFromLocalAudioMedia("sendonly");
+
+    sdpSession->addAttributeToLocalAudioMedia("sendrecv");
 
     /* Create re-INVITE with new offer */
-    status = SIPInvSessionReinvite (call, "sendonly");
+    status = SIPSessionReinvite (call);
 
-    if (status != PJ_SUCCESS)
+    if (status != PJ_SUCCESS) {
         return false;
+    }
+
+    call->setState (Call::Active);
 
     return true;
 }
@@ -968,14 +1042,12 @@ SIPVoIPLink::sendTextMessage (sfl::InstantMessaging *module, const std::string&
     return status;
 }
 
-int SIPVoIPLink::SIPInvSessionReinvite (SIPCall *call, std::string direction)
+int SIPVoIPLink::SIPSessionReinvite (SIPCall *call)
 {
 
     pj_status_t status;
     pjsip_tx_data *tdata;
     pjmedia_sdp_session *local_sdp;
-    pjmedia_sdp_attr *attr;
-    pj_pool_t *call_memory_pool;
 
     if (call == NULL) {
         _error ("UserAgent: Error: Call is NULL in session reinvite");
@@ -987,32 +1059,8 @@ int SIPVoIPLink::SIPInvSessionReinvite (SIPCall *call, std::string direction)
         return !PJ_SUCCESS;
     }
 
-    if ( (call_memory_pool = call->getLocalSDP()->getMemoryPool()) == NULL) {
-        _debug ("UserAgent: Error: Unable to find call memory pool");
-        return !PJ_SUCCESS;
-    }
-
-    // Reinvite only if connected
-    // Build the local SDP offer
-    // TODO Restore Re-Invite
-    // status = call->getLocalSDP()->create_initial_offer();
-
-    // if (status != PJ_SUCCESS)
-    // return 1;   // !PJ_SUCCESS
-
-
-    pjmedia_sdp_media_remove_all_attr (local_sdp->media[0], "sendrecv");
-    pjmedia_sdp_media_remove_all_attr (local_sdp->media[0], "sendonly");
-
-    attr = pjmedia_sdp_attr_create (call_memory_pool, direction.c_str(), NULL);
-
-    pjmedia_sdp_media_add_attr (local_sdp->media[0], attr);
-
-    // pjmedia_sdp_neg_modify_local_offer (_pool, call->getLocalSDP()->_negociator, local_sdp);
-
     // Build the reinvite request
-    status = pjsip_inv_reinvite (call->getInvSession(), NULL,
-                                 local_sdp, &tdata);
+    status = pjsip_inv_reinvite (call->getInvSession(), NULL, local_sdp, &tdata);
 
     if (status != PJ_SUCCESS)
         return 1;   // !PJ_SUCCESS
@@ -1026,59 +1074,6 @@ int SIPVoIPLink::SIPInvSessionReinvite (SIPCall *call, std::string direction)
     return PJ_SUCCESS;
 }
 
-
-bool
-SIPVoIPLink::offhold (const CallID& id)
-{
-    SIPCall *call;
-    pj_status_t status;
-
-    _debug ("UserAgent: retrive call from hold status");
-
-    call = getSIPCall (id);
-
-    if (call==0) {
-        _debug ("! SIP Error: Call doesn't exist");
-        return false;
-    }
-
-    // Retreive previously selected codec
-    sfl::Codec *sessionMedia = call->getLocalSDP()->getSessionMedia();
-
-    if (!sessionMedia)
-        return false;
-
-    // Get PayloadType for this codec
-    AudioCodecType pl = (AudioCodecType) sessionMedia->getPayloadType();
-
-    _debug ("UserAgent: Payload from session media %d", pl);
-
-    try {
-        // Create a new instance for this codec
-        sfl::Codec* audiocodec = Manager::instance().getCodecDescriptorMap().instantiateCodec (pl);
-
-        if (audiocodec == NULL)
-            _error ("UserAgent: No audiocodec found");
-
-        call->getAudioRtp()->initAudioRtpConfig (call);
-        call->getAudioRtp()->initAudioRtpSession (call);
-        call->getAudioRtp()->start (static_cast<AudioCodec *>(audiocodec));
-
-    } catch (...) {
-        _debug ("! SIP Failure: Unable to create RTP Session (%s:%d)", __FILE__, __LINE__);
-    }
-
-    /* Create re-INVITE with new offer */
-    status = SIPInvSessionReinvite (call, "sendrecv");
-
-    if (status != PJ_SUCCESS)
-        return false;
-
-    call->setState (Call::Active);
-
-    return true;
-}
-
 bool
 SIPVoIPLink::transfer (const CallID& id, const std::string& to)
 {
diff --git a/sflphone-common/src/sip/sipvoiplink.h b/sflphone-common/src/sip/sipvoiplink.h
index 76fc82553814c246361dc6c393c3d69b2de75cf1..abcd552abb029d7ac9d490e089765125cc649c1d 100644
--- a/sflphone-common/src/sip/sipvoiplink.h
+++ b/sflphone-common/src/sip/sipvoiplink.h
@@ -300,18 +300,18 @@ class SIPVoIPLink : public VoIPLink
         /**
          * Handle a re-invite request by the remote peer.
          * A re-invite is an invite request inside a dialog.
-         * When receiving a re-invite, we close the current rtp session and create
-         * a new one with the updated information
+         * When receiving a re-invite, we updated information
+         * concerning medias
          * @param sip call
          */
         void SIPHandleReinvite (SIPCall *call);
 
         /**
          * Send a reINVITE inside an active dialog to modify its state
+         * Local SDP session should be modified before calling this method
          * @param sip call
-         * @param the direction, "sendrecv" or "sendonly"
          */
-        int SIPInvSessionReinvite (SIPCall *call, std::string direction="");
+        int SIPSessionReinvite (SIPCall *call);
 
         pj_caching_pool *getMemoryPoolFactory();