Module: sems Branch: master Commit: fd592729478cd1bf2899eecb06af0c77806f720c URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=fd592729478cd1bf2899eecb06af0c77806f720c
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Tue Dec 13 15:06:36 2011 +0100 adds support for sendrecv/sendonly/recvonly/inactive SDP attributes Also re-enabled support for 'hold' and 'mute' - 'hold' in set by application via setOnHold(). It is not touched by any attribute received in SDP. - 'mute' is set according to attributes received in SDP. 'send' and 'recv' attributes in SDP are mirrored based on SDP received and overridden by application settings. For example: - if remote SDP says 'sendrecv', but local is 'on_hold', we reply with 'sendonly'. - if remote SDP says 'sendonly', but local is NOT 'on_hold', we reply with 'recvonly'. --- core/AmRtpStream.cpp | 50 ++++++++++++++++++++++++++++++-------------------- core/AmRtpStream.h | 3 +++ core/AmSdp.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- core/AmSdp.h | 11 ++++++++--- core/AmSession.cpp | 8 +++++++- 5 files changed, 94 insertions(+), 27 deletions(-) diff --git a/core/AmRtpStream.cpp b/core/AmRtpStream.cpp index c370554..8bece6b 100644 --- a/core/AmRtpStream.cpp +++ b/core/AmRtpStream.cpp @@ -550,12 +550,19 @@ void AmRtpStream::setPassiveMode(bool p) DBG("The other UA is NATed: switched to passive mode.\n"); } +void AmRtpStream::getSdp(SdpMedia& m) +{ + m.port = getLocalPort(); + m.nports = 0; + m.transport = TP_RTPAVP; + m.send = !hold; + m.recv = receiving; + m.dir = SdpMedia::DirBoth; +} + void AmRtpStream::getSdpOffer(SdpMedia& offer) { - offer.port = getLocalPort(); - offer.nports = 0; - offer.transport = TP_RTPAVP; - offer.dir = SdpMedia::DirBoth; + getSdp(offer); // TODO: transfer ownership of the payload provider also into AmRtpStream session->getPayloadProvider()->getPayloads(offer.payloads); @@ -563,21 +570,7 @@ void AmRtpStream::getSdpOffer(SdpMedia& offer) void AmRtpStream::getSdpAnswer(const SdpMedia& offer, SdpMedia& answer) { - answer.port = getLocalPort(); - answer.nports = 0; - answer.transport = TP_RTPAVP; - - switch(offer.dir){ - case SdpMedia::DirBoth: - answer.dir = SdpMedia::DirBoth; - break; - case SdpMedia::DirActive: - answer.dir = SdpMedia::DirPassive; - break; - case SdpMedia::DirPassive: - answer.dir = SdpMedia::DirActive; - break; - } + getSdp(answer); // TODO: transfer ownership of the payload provider also into AmRtpStream offer.calcAnswer(session->getPayloadProvider(),answer); @@ -682,7 +675,24 @@ int AmRtpStream::init(AmPayloadProviderInterface* payload_provider, local_telephone_event_pt.reset(local.telephoneEventPayload()); - resume(); + if(remote_media.send) { + resume(); + } + else { + pause(); + } + + if(remote_media.recv && !hold + && (remote_media.port != 0) +#ifndef SUPPORT_IPV6 + && (r_saddr.sin_addr.s_addr != 0) +#endif + ) { + mute = false; + } + else { + mute = true; + } #ifdef WITH_ZRTP if( session->zrtp_audio ) { diff --git a/core/AmRtpStream.h b/core/AmRtpStream.h index 8aa3174..a006d0a 100644 --- a/core/AmRtpStream.h +++ b/core/AmRtpStream.h @@ -198,6 +198,9 @@ protected: void relay(AmRtpPacket* p); + /** Sets generic parameters on SDP media */ + void getSdp(SdpMedia& m); + public: AmRtpPacket* newPacket(); diff --git a/core/AmSdp.cpp b/core/AmSdp.cpp index d5b2ac0..6a3859f 100644 --- a/core/AmSdp.cpp +++ b/core/AmSdp.cpp @@ -223,6 +223,23 @@ void AmSdp::print(string& body) const default: break; } + if(media_it->send){ + if(media_it->recv){ + out_buf += "a=sendrecv\r\n"; + } + else { + out_buf += "a=sendonly\r\n"; + } + } + else { + if(media_it->recv){ + out_buf += "a=recvonly\r\n"; + } + else { + out_buf += "a=inactive\r\n"; + } + } + // add attributes (media level) for (std::vector<SdpAttribute>::const_iterator a_it= media_it->attributes.begin(); a_it != media_it->attributes.end(); a_it++) { @@ -279,6 +296,21 @@ void AmSdp::clear() void SdpMedia::calcAnswer(const AmPayloadProviderInterface* payload_prov, SdpMedia& answer) const { + if(!recv) answer.send = false; + if(!send) answer.recv = false; + + switch(dir){ + case SdpMedia::DirBoth: + answer.dir = SdpMedia::DirBoth; + break; + case SdpMedia::DirActive: + answer.dir = SdpMedia::DirPassive; + break; + case SdpMedia::DirPassive: + answer.dir = SdpMedia::DirActive; + break; + } + // Calculate the intersection with the offered set of payloads vector<SdpPayload>::const_iterator it = payloads.begin(); for(; it!= payloads.end(); ++it) { @@ -306,7 +338,7 @@ void SdpMedia::calcAnswer(const AmPayloadProviderInterface* payload_prov, it->encoding_name,it->clock_rate,it->encoding_param)); } } - } + } } //parser @@ -883,8 +915,19 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) DBG("found media attr 'direction', but value is not" " followed by cr\n"); } - - }else{ + } else if (attr == "sendrecv") { + media.send = true; + media.recv = true; + } else if (attr == "sendonly") { + media.send = true; + media.recv = false; + } else if (attr == "recvonly") { + media.send = false; + media.recv = true; + } else if (attr == "inactive") { + media.send = false; + media.recv = false; + } else { attr_check(attr); next = parse_until(attr_line, '\r'); if(next < line_end){ diff --git a/core/AmSdp.h b/core/AmSdp.h index fa9116a..4bbdc6e 100644 --- a/core/AmSdp.h +++ b/core/AmSdp.h @@ -141,15 +141,20 @@ struct SdpMedia SdpConnection conn; // c= Direction dir; // a=direction + // sendrecv|sendonly|recvonly|inactive + bool send; + bool recv; + std::vector<SdpPayload> payloads; std::vector<SdpAttribute> attributes; // unknown attributes - SdpMedia() : conn() {} + SdpMedia() : conn(),send(true),recv(true) {} /** - * Checks which payloads are compatible with the payload provider - * and inserts them into the answer. + * Checks which payloads are compatible with the payload provider, + * inserts them into the answer, compute send/recv attributes + * and direction according to the offer. */ void calcAnswer(const AmPayloadProviderInterface* payload_prov, SdpMedia& answer) const; diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 3530c95..2fac67f 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -993,7 +993,9 @@ bool AmSession::getSdpAnswer(const AmSdp& offer, AmSdp& answer) answer.media.push_back(SdpMedia()); SdpMedia& answer_media = answer.media.back(); - if(m_it->type == MT_AUDIO && audio_1st_stream) { + if( m_it->type == MT_AUDIO + && audio_1st_stream + && (m_it->port != 0) ) { RTPStream()->getSdpAnswer(*m_it,answer_media); audio_1st_stream = false; @@ -1004,7 +1006,11 @@ bool AmSession::getSdpAnswer(const AmSdp& offer, AmSdp& answer) answer_media.port = 0; answer_media.nports = 0; answer_media.transport = TP_RTPAVP; + answer_media.send = false; + answer_media.recv = false; answer_media.payloads.clear(); + if(!m_it->payloads.empty()) + answer_media.payloads.push_back(m_it->payloads.front()); answer_media.attributes.clear(); } } _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
