From b61c3339cd3c926091cfb34fdbbe07bf994b7dc0 Mon Sep 17 00:00:00 2001 From: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Date: Thu, 5 Mar 2009 11:34:32 -0500 Subject: [PATCH] Fix media port problem; set the session media resulting of the sdp negociated --- src/audio/audiortp.cpp | 7 ++-- src/sdp.cpp | 59 +++++++++++++++++++++----------- src/sdp.h | 25 ++++++-------- src/sipvoiplink.cpp | 78 +++++++++++++++++++++++------------------- 4 files changed, 96 insertions(+), 73 deletions(-) diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index 7810bc9c5c..c6666e36b0 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -190,10 +190,13 @@ AudioRtpRTX::initAudioRtpSession (void) try { if (_ca == 0) { return; } - _audiocodec = Manager::instance().getCodecDescriptorMap().getCodec( _ca->getLocalSDP()->getAudioCodec() ); + _audiocodec = _ca->getLocalSDP()->get_session_media (); + + if(_audiocodec == 0) { return; } + _codecSampleRate = _audiocodec->getClockRate(); - remoteIP = _ca->getLocalSDP()->getRemoteIp(); + remoteIP = _ca->getRemoteIp(); _debug("Init audio RTP session - remote IP = %s\n", remoteIP.c_str()); ost::InetHostAddress remote_ip(remoteIP.c_str()); if (!remote_ip) { diff --git a/src/sdp.cpp b/src/sdp.cpp index 6eea13899f..b4b813ada4 100644 --- a/src/sdp.cpp +++ b/src/sdp.cpp @@ -32,7 +32,7 @@ static const pj_str_t STR_RTP_AVP = { (char*)"RTP/AVP", 7 }; static const pj_str_t STR_SDP_NAME = { (char*)"sflphone", 7 }; static const pj_str_t STR_SENDRECV = { (char*)"sendrecv", 8 }; - Sdp::Sdp( pj_pool_t *pool, int port ) + Sdp::Sdp( pj_pool_t *pool ) : _local_media_cap(), _session_media(0), _ip_addr( "" ), _local_offer( NULL ), _negociated_offer(NULL), _negociator(NULL), _pool(NULL) { _pool = pool; @@ -55,7 +55,7 @@ void Sdp::set_media_descriptor_line( sdpMedia *media, pjmedia_sdp_attr *attr; AudioCodec *codec; int count, i; - std::ostringstream tmp; + std::string tmp; med = PJ_POOL_ZALLOC_T( _pool, pjmedia_sdp_media ); @@ -63,7 +63,7 @@ void Sdp::set_media_descriptor_line( sdpMedia *media, pj_strdup(_pool, &med->desc.media, ( media->get_media_type() == MIME_TYPE_AUDIO ) ? &STR_AUDIO : &STR_VIDEO ); med->desc.port_count = 1; - med->desc.port = 65555; //media->get_port(); + med->desc.port = media->get_port(); pj_strdup (_pool, &med->desc.transport, &STR_RTP_AVP); // Media format ( RTP payload ) @@ -73,8 +73,9 @@ void Sdp::set_media_descriptor_line( sdpMedia *media, // add the payload list for(i=0; i<count; i++){ codec = media->get_media_codec_list()[i]; - tmp << codec->getPayload (); - pj_strdup2( _pool, &med->desc.fmt[i], tmp.str().c_str()); + tmp = this->convert_int_to_string (codec->getPayload ()); + _debug ("%s\n", tmp.c_str()); + pj_strdup2( _pool, &med->desc.fmt[i], tmp.c_str()); // Add a rtpmap field for each codec // We could add one only for dynamic payloads because the codecs with static RTP payloads @@ -122,7 +123,6 @@ int Sdp::create_local_offer (){ //sdp_addAttributes( _pool ); sdp_add_media_description( ); - _debug ("local port = %i\n", _localAudioPort); toString (); // Validate the sdp session @@ -192,9 +192,6 @@ void Sdp::sdp_add_origin( void ){ this->_local_offer->origin.addr = pj_str( (char*)_ip_addr.c_str() ); } - - - void Sdp::sdp_add_session_name( void ){ this->_local_offer->name = STR_SDP_NAME; } @@ -306,6 +303,7 @@ AudioCodec* Sdp::get_session_media( void ){ void Sdp::toString (void) { std::ostringstream sdp; + int count, i; sdp << "origin= " << _local_offer->origin.user.ptr << "\n"; sdp << "origin.id= " << _local_offer->origin.id << "\n"; @@ -324,11 +322,14 @@ void Sdp::toString (void) { sdp << "attr_count=" << _local_offer->attr_count << "\n"; sdp << "media_count=" << _local_offer->media_count << "\n"; - sdp << "m=" << _local_offer->media[0]->desc.media.ptr << "\n"; - sdp << "port=" << _local_offer->media[0]->desc.port << "\n"; - sdp << "transport=" << _local_offer->media[0]->desc.transport.ptr << "\n"; - sdp << "fmt_count=" << _local_offer->media[0]->desc.fmt_count << "\n"; - sdp << "fmt=" << _local_offer->media[0]->desc.fmt[0].ptr << "\n"; + sdp << "m=" << _local_offer->media[0]->desc.media.ptr << " "; + sdp << _local_offer->media[0]->desc.port << " "; + sdp << _local_offer->media[0]->desc.transport.ptr << " "; + count = _local_offer->media[0]->desc.fmt_count; + for (i=0; i<count; i++) { + sdp << _local_offer->media[0]->desc.fmt[i].ptr << " "; + } + sdp << "\n"; _debug ("LOCAL SDP: \n%s\n", sdp.str().c_str()); @@ -352,13 +353,31 @@ void Sdp::set_local_media_capabilities () { selected_codecs = Manager::instance().getCodecDescriptorMap().getActiveCodecs(); codecs_list = Manager::instance().getCodecDescriptorMap().getCodecsMap(); for (i=0; i<selected_codecs.size(); i++){ - iter = codecs_list.find(selected_codecs[i]); - - if (iter==codecs_list.end()) - return; - - audio->add_codec (iter->second); + iter=codecs_list.find(selected_codecs[i]); + if (iter!=codecs_list.end()){ + audio->add_codec (iter->second); + } } _local_media_cap.push_back (audio); _debug ("%s\n", audio->to_string ().c_str()); } + +void Sdp::attribute_port_to_all_media (int port) { + + std::vector<sdpMedia*> medias; + int i, size; + + medias = get_local_media_cap (); + size = medias.size(); + + for(i=0; i<size; i++) { + medias[i]->set_port (port); + } + +} + +std::string Sdp::convert_int_to_string (int value) { + std::ostringstream result; + result << value; + return result.str(); +} diff --git a/src/sdp.h b/src/sdp.h index 07e1c28dee..6bd55777f1 100644 --- a/src/sdp.h +++ b/src/sdp.h @@ -52,8 +52,6 @@ class Sdp { */ std::vector<sdpMedia*> get_local_media_cap( void ) { return _local_media_cap; } - void set_local_media_cap (void); - /* * Read accessor. Get the sdp session information * @@ -142,6 +140,14 @@ class Sdp { */ void set_negociated_offer( const pjmedia_sdp_session *sdp ); + /* + * Attribute the specified port to every medias provided + * This is valid only because we are using one media + * We should change this to support multiple medias + * + * @param port The media port + */ + void attribute_port_to_all_media (int port); ///////////////////////////////////////////////////////////////////////////33 void setLocalExternAudioPort(int port){ _localAudioPort = port; } @@ -150,8 +156,6 @@ class Sdp { void toString (void); - AudioCodecType getAudioCodec (void) { return _audioCodec; } - /** * Set remote's IP addr. [not protected] * @param ip The remote IP address @@ -179,12 +183,6 @@ class Sdp { ///////////////////////////////////////////////////////////////////////// private: - /** - * Set the audio codec used. [not protected] - * @param audioCodec The payload of the codec - */ - void setAudioCodec(AudioCodecType audioCodec) { _audioCodec = audioCodec; } - /** Codec Map */ std::vector<sdpMedia*> _local_media_cap; @@ -288,19 +286,16 @@ class Sdp { */ void sdp_add_media_description(); + std::string convert_int_to_string (int value); + int _localAudioPort; //////////////////////////////////////////////////////////////////3 - /** Codec pointer */ - AudioCodecType _audioCodec; - - /** Remote's IP address */ std::string _remoteIPAddress; /** Remote's audio port */ unsigned int _remoteAudioPort; - //////////////////////////////////////////////////////////////////// }; diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 6aa49bb68e..d1869d176d 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -39,6 +39,14 @@ void get_remote_sdp_from_offer( pjsip_rx_data *rdata, pjmedia_sdp_session** r_sd int getModId(); +/** + * * Set audio (SDP) configuration for a call + * * localport, localip, localexternalport + * * @param call a SIPCall valid pointer + * * @return bool True + * */ +bool setCallAudioLocal(SIPCall* call, std::string localIP, bool stun, std::string server); + /* * The global pool factory */ @@ -70,14 +78,6 @@ pj_thread_desc desc; */ void set_voicemail_info( AccountID account, pjsip_msg_body *body ); -/** - * Set audio (SDP) configuration for a call - * localport, localip, localexternalport - * @param call a SIPCall valid pointer - * @return bool True - */ -bool setCallAudioLocal(SIPCall* call, std::string localIP, bool stun, std::string server); - // Documentated from the PJSIP Developer's Guide, available on the pjsip website/ /* @@ -995,29 +995,6 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam return true; } - bool setCallAudioLocal(SIPCall* call, std::string localIP, bool stun, std::string server) - { - // Setting Audio - unsigned int callLocalAudioPort = RANDOM_LOCAL_PORT; - unsigned int callLocalExternAudioPort = callLocalAudioPort; - if (stun) { - // If use Stun server - if (Manager::instance().behindNat(server, callLocalAudioPort)) { - callLocalExternAudioPort = Manager::instance().getFirewallPort(); - } - } - _debug(" Setting local audio port to: %d\n", callLocalAudioPort); - _debug(" Setting local audio port (external) to: %d\n", callLocalExternAudioPort); - - // Set local audio port for SIPCall(id) - call->setLocalIp(localIP); - call->setLocalAudioPort(callLocalAudioPort); - call->setLocalExternAudioPort(callLocalExternAudioPort); - call->getLocalSDP()->setLocalExternAudioPort(callLocalExternAudioPort); - - return true; - } - void SIPVoIPLink::SIPCallServerFailure(SIPCall *call) { @@ -1579,19 +1556,25 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam } } - void call_on_media_update( pjsip_inv_session *inv UNUSED, pj_status_t status UNUSED) { + void call_on_media_update( pjsip_inv_session *inv, pj_status_t status) { _debug("call_on_media_updated\n"); const pjmedia_sdp_session *r_sdp; + SIPCall *call; if (status != PJ_SUCCESS) { + _debug ("Error while negociating the offer\n"); return; } // Get the new sdp, result of the negociation pjmedia_sdp_neg_get_active_local( inv->neg, &r_sdp ); - + + call = reinterpret_cast<SIPCall *> (inv->mod_data[getModId()]); // Clean the resulting sdp offer to create a new one (in case of a reinvite) + call->getLocalSDP()->clean_session_media(); + // Set the fresh negociated one + call->getLocalSDP()->set_negociated_offer( r_sdp ); } void call_on_forked(pjsip_inv_session *inv, pjsip_event *e){ @@ -1884,13 +1867,13 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam } // Have to do some stuff with the SDP + // Set the codec map, IP, peer number and so on... for the SIPCall object + setCallAudioLocal(call, link->getLocalIPAddress(), link->useStun(), link->getStunServer()); // We retrieve the remote sdp offer in the rdata struct to begin the negociation call->getLocalSDP()->set_ip_address(link->getLocalIPAddress()); get_remote_sdp_from_offer( rdata, &r_sdp ); call->getLocalSDP()->receiving_initial_offer( r_sdp ); - // Set the codec map, IP, peer number and so on... for the SIPCall object - setCallAudioLocal(call, link->getLocalIPAddress(), link->useStun(), link->getStunServer()); call->setConnectionState(Call::Progressing); call->setPeerNumber(peerNumber); @@ -2344,10 +2327,33 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam return; call->getLocalSDP()->receiving_initial_offer( (pjmedia_sdp_session*)offer); - _debug("audio codec setté dans l'objet call: %i\n", call->getLocalSDP()->getAudioCodec()); status=pjsip_inv_set_sdp_answer( call->getInvSession(), call->getLocalSDP()->get_local_sdp_session() ); #endif } +bool setCallAudioLocal(SIPCall* call, std::string localIP, bool stun, std::string server) { + // Setting Audio + unsigned int callLocalAudioPort = RANDOM_LOCAL_PORT; + unsigned int callLocalExternAudioPort = callLocalAudioPort; + if (stun) { + // If use Stun server + if (Manager::instance().behindNat(server, callLocalAudioPort)) { + callLocalExternAudioPort = Manager::instance().getFirewallPort(); + } + } + _debug(" Setting local audio port to: %d\n", callLocalAudioPort); + _debug(" Setting local audio port (external) to: %d\n", callLocalExternAudioPort); + + // Set local audio port for SIPCall(id) + call->setLocalIp(localIP); + call->setLocalAudioPort(callLocalAudioPort); + call->setLocalExternAudioPort(callLocalExternAudioPort); + + call->getLocalSDP()->attribute_port_to_all_media (callLocalExternAudioPort); + + return true; +} + + -- GitLab