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();