r2613 - trunk/libminisip/source/mediahandler
werner at minisip.org
werner at minisip.org
Sun Jun 4 10:08:04 CEST 2006
Author: werner
Date: 2006-06-04 10:08:03 +0200 (Sun, 04 Jun 2006)
New Revision: 2613
Modified:
trunk/libminisip/source/mediahandler/MediaHandler.cxx
trunk/libminisip/source/mediahandler/MediaStream.cxx
trunk/libminisip/source/mediahandler/RtpReceiver.cxx
Log:
Add ZRTP support, protected with #ifdef ZRTP_SUPPORT
Modified: trunk/libminisip/source/mediahandler/MediaHandler.cxx
===================================================================
--- trunk/libminisip/source/mediahandler/MediaHandler.cxx 2006-06-04 08:07:43 UTC (rev 2612)
+++ trunk/libminisip/source/mediahandler/MediaHandler.cxx 2006-06-04 08:08:03 UTC (rev 2613)
@@ -1,247 +1,266 @@
-/*
- Copyright (C) 2004-2006 the Minisip Team
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Copyright (C) 2004, 2005, 2006
- *
- * Authors: Erik Eliasson <eliasson at it.kth.se>
- * Johan Bilien <jobi at via.ecp.fr>
-*/
-
-#include <config.h>
-
-#include<libminisip/mediahandler/MediaHandler.h>
-
-#include<string.h>
-#include<libminisip/sdp/SdpPacket.h>
-#include<libmikey/keyagreement.h>
-#include<libminisip/sip/SipDialogSecurityConfig.h>
-#include<libminisip/sip/SipSoftPhoneConfiguration.h>
-#include<libminisip/ipprovider/IpProvider.h>
-#include<libminisip/codecs/Codec.h>
-#include<libminisip/mediahandler/Session.h>
-#include<libminisip/mediahandler/MediaStream.h>
-
-#include<libminisip/mediahandler/Media.h>
-#include<libminisip/mediahandler/RtpReceiver.h>
-#include<libminisip/mediahandler/MediaCommandString.h>
-#include<libmnetutil/UDPSocket.h>
-
-#include<libminisip/soundcard/SoundIO.h>
-#include<libminisip/soundcard/SoundDevice.h>
-#include<libminisip/codecs/Codec.h>
-
-#ifdef _WIN32_WCE
-# include"../include/minisip_wce_extra_includes.h"
-#endif
-
-
-
-using namespace std;
-
-MediaHandler::MediaHandler( MRef<SipSoftPhoneConfiguration *> config, MRef<IpProvider *> ipProvider ){
-
- this->ipProvider = ipProvider;
- this->config = config;
- init();
-}
-
-MediaHandler::~MediaHandler(){
-// cerr << "~MediaHandler" << end;
-}
-
-void MediaHandler::init(){
-
- media.clear();
-
- MRef<MediaRegistry*> registry = MediaRegistry::getInstance();
- MediaRegistry::const_iterator i;
- MediaRegistry::const_iterator last = registry->end();
-
- for( i = registry->begin(); i != last; i++ ){
- MRef<MPlugin *> plugin = *i;
- MRef<MediaPlugin *> mediaPlugin = dynamic_cast<MediaPlugin*>( *plugin );
- if( mediaPlugin ){
- MRef<Media *> media = mediaPlugin->createMedia( config );
- MRef<AudioMedia *> audio = dynamic_cast<AudioMedia *>( *media );
-
- if( media ){
- registerMedia( media );
- }
-
- if( !audioMedia && audio ){
- audioMedia = audio;
- }
- }
- }
-
-// muteAllButOne = config->muteAllButOne;
-
- ringtoneFile = config->ringtone;
-}
-
-// MediaHandler::~MediaHandler() {
-// cerr << "~MediaHandler" << endl;
-// if( ! Session::registry ){
-// cerr << "deleting session::registry" << endl;
-// }
-// }
-
-
-MRef<Session *> MediaHandler::createSession( SipDialogSecurityConfig &securityConfig, string callId ){
-
- list< MRef<Media *> >::iterator i;
- MRef<Session *> session;
- MRef<MediaStreamReceiver *> rStream;
- MRef<MediaStreamSender *> sStream;
- MRef<RtpReceiver *> rtpReceiver = NULL;
- string contactIp;
-
- contactIp = ipProvider->getExternalIp();
-
- session = new Session( contactIp, securityConfig );
- session->setCallId( callId );
-
- for( i = media.begin(); i != media.end(); i++ ){
- MRef<Media *> media = *i;
-
- if( media->receive ){
- rtpReceiver = new RtpReceiver( ipProvider );
- rStream = new MediaStreamReceiver( media, rtpReceiver, ipProvider );
- session->addMediaStreamReceiver( rStream );
- }
-
- if( media->send ){
- if( !rtpReceiver ){
- rtpReceiver = new RtpReceiver( ipProvider );
- }
- sStream = new MediaStreamSender( media, rtpReceiver->getSocket() );
- session->addMediaStreamSender( sStream );
- }
- }
-
- //set the audio settings for this session ...
- session->muteSenders( true );
- session->silenceSources( false );
-
- return session;
-
-}
-
-
-void MediaHandler::registerMedia( MRef<Media*> media ){
- this->media.push_back( media );
-}
-
-CommandString MediaHandler::handleCommandResp(string, const CommandString& c){
- assert(1==0); //Not used
- return c; // Not reached; masks warning
-}
-
-
-void MediaHandler::handleCommand(string subsystem, const CommandString& command ){
- assert(subsystem=="media");
-
- if( command.getOp() == MediaCommandString::start_ringing ){
-// cerr << "MediaHandler::handleCmd - start ringing" << endl;
- if( audioMedia && ringtoneFile != "" ){
- audioMedia->startRinging( ringtoneFile );
- }
- return;
- }
-
- if( command.getOp() == MediaCommandString::stop_ringing ){
-// cerr << "MediaHandler::handleCmd - stop ringing" << endl;
- if( audioMedia ){
- audioMedia->stopRinging();
- }
- return;
- }
-
- if( command.getOp() == MediaCommandString::session_debug ){
-#ifdef DEBUG_OUTPUT
- cerr << getDebugString() << endl;
-#endif
- return;
- }
-
- if( command.getOp() == MediaCommandString::set_session_sound_settings ){
- bool turnOn;
-#ifdef DEBUG_OUTPUT
- cerr << "MediaHandler::handleCmd: received set session sound settings"
- << endl << " " << command.getString() << endl;
-#endif
- if( command.getParam2() == "ON" ) turnOn = true;
- else turnOn = false;
- setSessionSoundSettings( command.getDestinationId(),
- command.getParam(),
- turnOn );
- return;
- }
-
- if( command.getOp() == MediaCommandString::reload ){
- init();
- return;
- }
-}
-
-std::string MediaHandler::getExtIP(){
- return ipProvider->getExternalIp();
-}
-
-void MediaHandler::setSessionSoundSettings( std::string callid, std::string side, bool turnOn ) {
- list<MRef<Session *> >::iterator iSession;
-
- //what to do with received audio
- if( side == "receivers" ) {
- sessionsLock.lock();
- for( iSession = sessions.begin(); iSession != sessions.end(); iSession++ ){
- if( (*iSession)->getCallId() == callid ){
- //the meaning of turnOn is the opposite of the Session:: functions ... silence/mute
- (*iSession)->silenceSources( ! turnOn );
- }
- }
- sessionsLock.unlock();
- } else if ( side == "senders" ) { //what to do with audio to be sent over the net
- //set the sender ON as requested ...
- sessionsLock.lock();
- for( iSession = sessions.begin(); iSession != sessions.end(); iSession++ ){
- if( (*iSession)->getCallId() == callid ){
- //the meaning of turnOn is the opposite of the Session:: functions ... silence/mute
- (*iSession)->muteSenders( !turnOn );
-
- }
- }
- sessionsLock.unlock();
- } else {
- cerr << "MediaHandler::setSessionSoundSettings - not understood" << endl;
- return;
- }
-
-}
-
-#ifdef DEBUG_OUTPUT
-string MediaHandler::getDebugString() {
- string ret;
- ret = getMemObjectType() + ": Debug Info\n";
- for( std::list<MRef<Session *> >::iterator it = sessions.begin();
- it != sessions.end(); it++ ) {
- ret += "** Session : \n" + (*it)->getDebugString() + "\n";
- }
- return ret;
-}
-#endif
+/*
+ Copyright (C) 2004-2006 the Minisip Team
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Copyright (C) 2004, 2005, 2006
+ *
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ * Johan Bilien <jobi at via.ecp.fr>
+*/
+
+#include <config.h>
+
+#include<libminisip/mediahandler/MediaHandler.h>
+
+#include<string.h>
+#include<libminisip/sdp/SdpPacket.h>
+#include<libmikey/keyagreement.h>
+#include<libminisip/sip/SipDialogSecurityConfig.h>
+#include<libminisip/sip/SipSoftPhoneConfiguration.h>
+#include<libminisip/ipprovider/IpProvider.h>
+#include<libminisip/codecs/Codec.h>
+#include<libminisip/mediahandler/Session.h>
+#include<libminisip/mediahandler/MediaStream.h>
+
+#include<libminisip/mediahandler/Media.h>
+#include<libminisip/mediahandler/RtpReceiver.h>
+#include<libminisip/mediahandler/MediaCommandString.h>
+#include<libmnetutil/UDPSocket.h>
+
+#include<libminisip/soundcard/SoundIO.h>
+#include<libminisip/soundcard/SoundDevice.h>
+#include<libminisip/codecs/Codec.h>
+
+#ifdef _WIN32_WCE
+# include"../include/minisip_wce_extra_includes.h"
+#endif
+
+
+
+using namespace std;
+
+MediaHandler::MediaHandler( MRef<SipSoftPhoneConfiguration *> config, MRef<IpProvider *> ipProvider ){
+
+ this->ipProvider = ipProvider;
+ this->config = config;
+ init();
+}
+
+MediaHandler::~MediaHandler(){
+// cerr << "~MediaHandler" << end;
+}
+
+void MediaHandler::init(){
+
+ media.clear();
+
+ MRef<MediaRegistry*> registry = MediaRegistry::getInstance();
+ MediaRegistry::const_iterator i;
+ MediaRegistry::const_iterator last = registry->end();
+
+ for( i = registry->begin(); i != last; i++ ){
+ MRef<MPlugin *> plugin = *i;
+ MRef<MediaPlugin *> mediaPlugin = dynamic_cast<MediaPlugin*>( *plugin );
+ if( mediaPlugin ){
+ MRef<Media *> media = mediaPlugin->createMedia( config );
+ MRef<AudioMedia *> audio = dynamic_cast<AudioMedia *>( *media );
+
+ if( media ){
+ registerMedia( media );
+ }
+
+ if( !audioMedia && audio ){
+ audioMedia = audio;
+ }
+ }
+ }
+
+// muteAllButOne = config->muteAllButOne;
+
+ ringtoneFile = config->ringtone;
+}
+
+// MediaHandler::~MediaHandler() {
+// cerr << "~MediaHandler" << endl;
+// if( ! Session::registry ){
+// cerr << "deleting session::registry" << endl;
+// }
+// }
+
+
+MRef<Session *> MediaHandler::createSession( SipDialogSecurityConfig &securityConfig, string callId ){
+
+ list< MRef<Media *> >::iterator i;
+ MRef<Session *> session;
+ MRef<MediaStreamReceiver *> rStream;
+ MRef<MediaStreamSender *> sStream;
+ MRef<RtpReceiver *> rtpReceiver = NULL;
+ string contactIp;
+#ifdef ZRTP_SUPPORT
+ MRef<ZrtpHostBridgeMinisip *> zhb = NULL;
+#endif
+
+ contactIp = ipProvider->getExternalIp();
+
+ session = new Session( contactIp, securityConfig );
+ session->setCallId( callId );
+
+ for( i = media.begin(); i != media.end(); i++ ){
+ MRef<Media *> media = *i;
+
+ if( media->receive ){
+ rtpReceiver = new RtpReceiver( ipProvider );
+ rStream = new MediaStreamReceiver( media, rtpReceiver, ipProvider );
+ session->addMediaStreamReceiver( rStream );
+#ifdef ZRTP_SUPPORT
+ if(securityConfig.use_zrtp) {
+ zhb = new ZrtpHostBridgeMinisip();
+ zhb->setReceiver(rStream);
+ rStream->setZrtpHostBridge(zhb);
+ }
+#endif
+ }
+
+ if( media->send ){
+ if( !rtpReceiver ){
+ rtpReceiver = new RtpReceiver( ipProvider );
+ }
+ sStream = new MediaStreamSender( media, rtpReceiver->getSocket() );
+ session->addMediaStreamSender( sStream );
+#ifdef ZRTP_SUPPORT
+ if(securityConfig.use_zrtp) {
+ if (!zhb) {
+ zhb = new ZrtpHostBridgeMinisip();
+ }
+ zhb->setSender(sStream);
+ sStream->setZrtpHostBridge(zhb);
+ }
+#endif
+ }
+ }
+
+ //set the audio settings for this session ...
+ session->muteSenders( true );
+ session->silenceSources( false );
+
+ return session;
+
+}
+
+
+void MediaHandler::registerMedia( MRef<Media*> media ){
+ this->media.push_back( media );
+}
+
+CommandString MediaHandler::handleCommandResp(string, const CommandString& c){
+ assert(1==0); //Not used
+ return c; // Not reached; masks warning
+}
+
+
+void MediaHandler::handleCommand(string subsystem, const CommandString& command ){
+ assert(subsystem=="media");
+
+ if( command.getOp() == MediaCommandString::start_ringing ){
+// cerr << "MediaHandler::handleCmd - start ringing" << endl;
+ if( audioMedia && ringtoneFile != "" ){
+ audioMedia->startRinging( ringtoneFile );
+ }
+ return;
+ }
+
+ if( command.getOp() == MediaCommandString::stop_ringing ){
+// cerr << "MediaHandler::handleCmd - stop ringing" << endl;
+ if( audioMedia ){
+ audioMedia->stopRinging();
+ }
+ return;
+ }
+
+ if( command.getOp() == MediaCommandString::session_debug ){
+#ifdef DEBUG_OUTPUT
+ cerr << getDebugString() << endl;
+#endif
+ return;
+ }
+
+ if( command.getOp() == MediaCommandString::set_session_sound_settings ){
+ bool turnOn;
+#ifdef DEBUG_OUTPUT
+ cerr << "MediaHandler::handleCmd: received set session sound settings"
+ << endl << " " << command.getString() << endl;
+#endif
+ if( command.getParam2() == "ON" ) turnOn = true;
+ else turnOn = false;
+ setSessionSoundSettings( command.getDestinationId(),
+ command.getParam(),
+ turnOn );
+ return;
+ }
+
+ if( command.getOp() == MediaCommandString::reload ){
+ init();
+ return;
+ }
+}
+
+std::string MediaHandler::getExtIP(){
+ return ipProvider->getExternalIp();
+}
+
+void MediaHandler::setSessionSoundSettings( std::string callid, std::string side, bool turnOn ) {
+ list<MRef<Session *> >::iterator iSession;
+
+ //what to do with received audio
+ if( side == "receivers" ) {
+ sessionsLock.lock();
+ for( iSession = sessions.begin(); iSession != sessions.end(); iSession++ ){
+ if( (*iSession)->getCallId() == callid ){
+ //the meaning of turnOn is the opposite of the Session:: functions ... silence/mute
+ (*iSession)->silenceSources( ! turnOn );
+ }
+ }
+ sessionsLock.unlock();
+ } else if ( side == "senders" ) { //what to do with audio to be sent over the net
+ //set the sender ON as requested ...
+ sessionsLock.lock();
+ for( iSession = sessions.begin(); iSession != sessions.end(); iSession++ ){
+ if( (*iSession)->getCallId() == callid ){
+ //the meaning of turnOn is the opposite of the Session:: functions ... silence/mute
+ (*iSession)->muteSenders( !turnOn );
+
+ }
+ }
+ sessionsLock.unlock();
+ } else {
+ cerr << "MediaHandler::setSessionSoundSettings - not understood" << endl;
+ return;
+ }
+
+}
+
+#ifdef DEBUG_OUTPUT
+string MediaHandler::getDebugString() {
+ string ret;
+ ret = getMemObjectType() + ": Debug Info\n";
+ for( std::list<MRef<Session *> >::iterator it = sessions.begin();
+ it != sessions.end(); it++ ) {
+ ret += "** Session : \n" + (*it)->getDebugString() + "\n";
+ }
+ return ret;
+}
+#endif
Modified: trunk/libminisip/source/mediahandler/MediaStream.cxx
===================================================================
--- trunk/libminisip/source/mediahandler/MediaStream.cxx 2006-06-04 08:07:43 UTC (rev 2612)
+++ trunk/libminisip/source/mediahandler/MediaStream.cxx 2006-06-04 08:08:03 UTC (rev 2613)
@@ -1,486 +1,636 @@
-/*
- Copyright (C) 2004-2006 the Minisip Team
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Copyright (C) 2004, 2005
- *
- * Authors: Erik Eliasson <eliasson at it.kth.se>
- * Johan Bilien <jobi at via.ecp.fr>
- * Joachim Orrblad <joachim at orrblad.com>
-*/
-
-#include <config.h>
-
-#include<libminisip/mediahandler/MediaStream.h>
-
-#include<libmikey/MikeyPayloadSP.h>
-#include<libmikey/keyagreement.h>
-#include<libminisip/sdp/SdpHeaderM.h>
-#include<libminisip/sdp/SdpHeaderA.h>
-#include<libminisip/sdp/SdpPacket.h>
-#include<libmnetutil/UDPSocket.h>
-#include<libmutil/itoa.h>
-#include<libmutil/Timestamp.h>
-#include<libmutil/print_hex.h>
-#include<libminisip/mediahandler/Media.h>
-#include<libminisip/mediahandler/RtpReceiver.h>
-#include<libminisip/codecs/Codec.h>
-#include<libminisip/ipprovider/IpProvider.h>
-#include<iostream>
-
-#ifdef _WIN32_WCE
-# include"../include/minisip_wce_extra_includes.h"
-#endif
-
-using namespace std;
-
-#ifdef _MSC_VER
-
-static int upcase(char c){
- if ((c>='a') && (c<='z'))
- return c - ('a'-'A');
- else
- return c;
-}
-
-static int nocaseequal(char c1, char c2){
- return upcase(c1)==upcase(c2);
-}
-
-static int strcasecmp(const char *s1, const char *s2){
- int i;
- for ( i=0; s1[i]!=0 && s2[i]!=0; i++){
- if ( !nocaseequal(s1[i],s2[i]) ){
- if (s1[i]<s2[i]){
- return -1;
- }else{
- return 1;
- }
- }
- }
- if (s2[i]!=0){
- return -1;
- }
- return 0;
-}
-#endif
-
-MediaStream::MediaStream( MRef<Media *> media ):media(media),ka(NULL){
- disabled = false;
-}
-
-std::string MediaStream::getSdpMediaType(){
- if( media ){
- return media->getSdpMediaType();
- }
- return "";
-}
-
-list<string> MediaStream::getSdpAttributes(){
- return media->getSdpAttributes();
-}
-
-bool MediaStream::matches( MRef<SdpHeaderM *> m, uint32_t formatIndex ){
- string sdpRtpMap;
- string sdpFmtpParam;
-
- // int i;
- uint8_t sdpPayloadType = (uint8_t) m->getFormat( formatIndex );
-
- media->handleMHeader( m );
-
- // pn507 This checks for "Audio"
- if( m->getMedia() != getSdpMediaType() ){
- return false;
- }
-
- sdpRtpMap = m->getRtpMap( sdpPayloadType );
- sdpFmtpParam = m->getFmtpParam( sdpPayloadType );
-
- std::list<MRef<Codec *> > codecs = media->getAvailableCodecs();
- std::list<MRef<Codec *> >::iterator iC;
- string codecRtpMap;
- uint8_t codecPayloadType;
-
- size_t s1;
- size_t s2 = sdpRtpMap.find("/");
-
- for( iC = codecs.begin(); iC != codecs.end(); iC ++ ){
- codecRtpMap = (*iC)->getSdpMediaAttributes();
- codecPayloadType = (*iC)->getSdpMediaType();
- if( (*iC)->getCodecName() == "iLBC" ) {
- if( sdpFmtpParam != "mode=20" ) { //iLBC only supports 20ms frames (in minisip)
- continue;
- } //else ... does not mean we accept it, it still goes through the normal checks ...
- }
- if( sdpRtpMap != "" && codecRtpMap != "" ){
- s1 = codecRtpMap.find("/");
- bool sdpRtpMapEqual = !strcasecmp( codecRtpMap.substr(0, s1).c_str(), sdpRtpMap.substr(0,s2).c_str() );
- if ( sdpRtpMapEqual ) {
- localPayloadType = codecPayloadType;
- return true;
- }
- else {
- continue;
- }
-
- }
- else{
- if( sdpPayloadType == codecPayloadType ){
- localPayloadType = codecPayloadType;
- return true;
- }else{
- }
- }
- }
- return false;
-}
-
-MRef<CryptoContext *> MediaStream::initCrypto( uint32_t ssrc, uint16_t seq_no ){
- MRef<CryptoContext *> cryptoContext;
-
- kaLock.lock();
- if( !ka ){
- /* Dummy cryptocontext */
- cryptoContext = new CryptoContext( ssrc );
- }
- else{
-
- unsigned char * masterKey = new unsigned char[16];
- unsigned char * masterSalt = new unsigned char[14];
-
- uint8_t csId = ka->getSrtpCsId( ssrc );
- uint32_t roc = ka->getSrtpRoc( ssrc );
- uint8_t policyNo = ka->findpolicyNo( ssrc );
- //Extract Srtp policy !!! Check the return value if type not available
- uint8_t ealg = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_EALG);
- uint8_t ekeyl = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_EKEYL);
- uint8_t aalg = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AALG);
- uint8_t akeyl = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AKEYL);
- uint8_t skeyl = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_SALTKEYL);
- //uint8_t prf = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_PRF); //Not used
- uint8_t keydr = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_KEY_DERRATE);
- uint8_t encr = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_ENCR_ON_OFF);
- //uint8_t cencr = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTCP_ENCR_ON_OFF);//Not used
- //uint8_t fecor = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_FEC_ORDER); //Not used
- uint8_t auth = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AUTH_ON_OFF);
- uint8_t autht = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AUTH_TAGL);
- //uint8_t prefi = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_PREFIX); //Not used
-
- ka->genTek( csId, masterKey, 16 );
- ka->genSalt( csId, masterSalt, 14 );
-
-#ifdef DEBUG_OUTPUT
-#if 0
- fprintf( stderr, "csId: %i\n", csId );
- cerr << "SSRC: "<< ssrc <<" - TEK: " << print_hex( masterKey, 16 ) << endl;
- cerr << "SSRC: "<< ssrc <<" - SALT: " << print_hex( masterSalt, 14 )<< endl;
-#endif
-#endif
-
- if( csId != 0 ){
- cryptoContext = new CryptoContext( ssrc, roc, seq_no, keydr,
- ealg, aalg, masterKey, 16, masterSalt, 14, ekeyl, akeyl, skeyl, encr, auth, autht );
-
- cryptoContext->derive_srtp_keys( 0 );
- }
- else{
- cryptoContext = new CryptoContext( ssrc );
- }
- }
-
- cryptoContexts.push_back( cryptoContext );
- kaLock.unlock();
- return cryptoContext;
-}
-
-MRef<CryptoContext *> MediaStream::getCryptoContext( uint32_t ssrc, uint16_t seq_no ){
- kaLock.lock();
- list< MRef<CryptoContext *> >::iterator i;
-
- for( i = cryptoContexts.begin(); i!= cryptoContexts.end(); i++ ){
- if( (*i)->getSsrc() == ssrc ){
- kaLock.unlock();
- return (*i);
- }
- }
-
- kaLock.unlock();
- return initCrypto( ssrc, seq_no );
-}
-
-void MediaStream::setKeyAgreement( MRef<KeyAgreement *> ka ){
- kaLock.lock();
- this->ka = ka;
-
- /* Reset the CryptoContext since we have a new KeyAgreement */
- cryptoContexts.clear();
-
- kaLock.unlock();
-}
-
-MediaStreamReceiver::MediaStreamReceiver( MRef<Media *> media,
- MRef<RtpReceiver *> rtpReceiver, MRef<IpProvider *> ipProvider ):
- MediaStream( media ),
- rtpReceiver( rtpReceiver ),
- ipProvider( ipProvider ){
- id = rand();
- externalPort = 0;
- running = false;
- codecList = media->getAvailableCodecs();
-}
-
-uint32_t MediaStreamReceiver::getId(){
- return id;
-}
-
-void MediaStreamReceiver::start(){
- if( !running ){
- rtpReceiver->registerMediaStream( this );
- running = true;
- }
-}
-
-void MediaStreamReceiver::stop(){
- list<uint32_t>::iterator i;
- rtpReceiver->unregisterMediaStream( this );
-
- ssrcListLock.lock();
- for( i = ssrcList.begin(); i != ssrcList.end(); i++ ){
- media->unRegisterMediaSource( *i );
- }
- ssrcList.clear();
- ssrcListLock.unlock();
-
- running = false;
-}
-
-uint16_t MediaStreamReceiver::getPort(){
- return rtpReceiver->getPort();
-}
-
-void MediaStreamReceiver::handleRtpPacket( MRef<SRtpPacket *> packet ){
- uint32_t packetSsrc;
- uint16_t seq_no;
-
- //if packet is null, we had a read timeout from the rtpReceiver
- if( !packet ) {
- return;
- }
-
- packetSsrc = packet->getHeader().getSSRC();
- seq_no = packet->getHeader().getSeqNo();
-
-
- if( packet->unprotect( getCryptoContext( packetSsrc, seq_no ) )){
- // Authentication or replay protection failed
- return;
- }
-
- //uint16_t seqNo = packet->getHeader().getSeqNo(); //not used
- //byte_t * data = packet->getContent(); //not used
- //uint32_t size = packet->getContentLength(); //not used
- //bool marker = packet->getHeader().getMarker(); //not used
- //uint32_t ts = packet->getHeader().getTimestamp(); //not used
-
- gotSsrc( packetSsrc );
-
- media->playData( *packet );
-}
-
-void MediaStreamReceiver::gotSsrc( uint32_t ssrc ){
- list<uint32_t>::iterator i;
-
- ssrcListLock.lock();
- for( i = ssrcList.begin(); i != ssrcList.end(); i++ ){
- if( (*i) == ssrc ){
- ssrcListLock.unlock();
- return;
- }
- }
-
- media->registerMediaSource( ssrc );
- ssrcList.push_back( ssrc );
- ssrcListLock.unlock();
-}
-
-std::list<MRef<Codec *> > MediaStreamReceiver::getAvailableCodecs(){
- return codecList;
-}
-
-MediaStreamSender::MediaStreamSender( MRef<Media *> media, MRef<UDPSocket *> senderSocket ):
- MediaStream( media ){
- selectedCodec = NULL;
- remotePort = 0;
- seqNo = (uint16_t)rand();
- ssrc = rand();
- lastTs = rand();
- payloadType = 255;
- setMuted( true );
- muteCounter = 0;
- if( senderSocket ){
- this->senderSock = senderSocket;
- }
- else{
- senderSock = new UDPSocket;
- senderSock->setLowDelay();
- }
-}
-
-void MediaStreamSender::start(){
- media->registerMediaSender( this );
-}
-
-void MediaStreamSender::stop(){
- media->unRegisterMediaSender( this );
-}
-
-void MediaStreamSender::setPort( uint16_t port ){
- remotePort = port;
-}
-
-uint16_t MediaStreamSender::getPort(){
- return remotePort;
-}
-
-static bool first=true;
-
-void MediaStreamSender::send( byte_t * data, uint32_t length, uint32_t * givenTs, bool marker, bool dtmf ){
- if (this->remoteAddress.isNull()) {
- mdbg << " MediaStreamSender::send called before " <<
- "setRemoteAddress!" << endl;
- return;
- }
- SRtpPacket * packet;
- if (first){
-#ifdef ENABLE_TS
- ts.save("rtp_send");
-#endif
- first=false;
- }
-
- senderLock.lock();
- if( !(*givenTs) ){
- //FIXME! get it from the CODEC,
- // when we have one CODEC per sender
- increaseLastTs(); //increase lastTs ...
- //lastTs += 160;
- *givenTs = lastTs;
- }
- else{
- lastTs = *givenTs;
- }
-
- packet = new SRtpPacket( data, length, seqNo++, lastTs, ssrc );
-
- if( dtmf ){
- packet->getHeader().setPayloadType( 101 );
- }
- else{
- if( payloadType != 255 )
- packet->getHeader().setPayloadType( payloadType );
- else
- packet->getHeader().setPayloadType( selectedCodec->getSdpMediaType() );
- }
-
- if( marker ){
- packet->getHeader().setMarker( marker );
- }
-
- packet->protect( getCryptoContext( ssrc, seqNo - 1 ) );
-
- packet->sendTo( **senderSock, **remoteAddress, remotePort );
- delete packet;
- senderLock.unlock();
-}
-
-void MediaStreamSender::setRemoteAddress( MRef<IPAddress *> remoteAddress ){
- mdbg << "MediaStreamSender::setRemoteAddress: " <<
- remoteAddress->getString() << endl;
- this->remoteAddress = remoteAddress;
-}
-
-#ifdef DEBUG_OUTPUT
-string MediaStream::getDebugString() {
- string ret;
- ret = getMemObjectType() + " this=" + itoa((int64_t)this) +
- ": port=" + itoa(getPort());
-
- return ret;
-}
-string MediaStreamReceiver::getDebugString() {
- string ret;
- ret = getMemObjectType() + " this=" + itoa((int64_t)this) +
- ": listening port=" + itoa(rtpReceiver->getPort());
- for( std::list<uint32_t>::iterator it = ssrcList.begin();
- it != ssrcList.end();
- it++) {
- "; ssrc=" + itoa((*it));
- }
- return ret;
-}
-string MediaStreamSender::getDebugString() {
- string ret;
-
- ret = getMemObjectType() + " this=" + itoa((int64_t)this) +
- ": port=" + itoa(getPort()) +
- "; remotePort=" + itoa(remotePort);
-
- if( isMuted() == true )
- ret += "; isMuted=true";
- else ret += "; isMuted=false";
-
- return ret;
-}
-#endif
-
-//keep a counter, so we can send a keep alive
-//packet every now and then.
-//Max indicates every how many silenced packets we send one keep-alive
-//It returns true if the packet needs to be let through, false otherwise
-bool MediaStreamSender::muteKeepAlive( uint32_t max ) {
- bool ret = false;
-
- //if muted, only return true if packet is keep alive
- if( isMuted() ) {
- muteCounter++;
- if( muteCounter >= max ) {
- ret = true;
- muteCounter = 0;
- }
- } else {
- //if active sender, let through
- ret = true;
- }
- return ret;
-}
-
-bool MediaStreamSender::matches( MRef<SdpHeaderM *> m, uint32_t formatIndex ){
- bool result = MediaStream::matches( m, formatIndex );
-
- if( result && !selectedCodec ){
- selectedCodec = media->createCodecInstance(
- localPayloadType );
- payloadType = (uint8_t)m->getFormat( formatIndex );
- }
-
- return result;
-}
-
-uint32_t MediaStreamSender::getSsrc(){
- return ssrc;
-}
+/*
+ Copyright (C) 2004-2006 the Minisip Team
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Copyright (C) 2004, 2005
+ *
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ * Johan Bilien <jobi at via.ecp.fr>
+ * Joachim Orrblad <joachim at orrblad.com>
+*/
+
+#include <config.h>
+
+#include<libminisip/mediahandler/MediaStream.h>
+
+#include<libmikey/MikeyPayloadSP.h>
+#include<libmikey/keyagreement.h>
+#include<libminisip/sdp/SdpHeaderM.h>
+#include<libminisip/sdp/SdpHeaderA.h>
+#include<libminisip/sdp/SdpPacket.h>
+#include<libmnetutil/UDPSocket.h>
+#include<libmutil/itoa.h>
+#include<libmutil/Timestamp.h>
+#include<libmutil/print_hex.h>
+#include<libminisip/mediahandler/Media.h>
+#include<libminisip/mediahandler/RtpReceiver.h>
+#include<libminisip/codecs/Codec.h>
+#include<libminisip/ipprovider/IpProvider.h>
+#include<iostream>
+
+#ifdef _WIN32_WCE
+# include"../include/minisip_wce_extra_includes.h"
+#endif
+
+using namespace std;
+
+#ifdef _MSC_VER
+
+static int upcase(char c){
+ if ((c>='a') && (c<='z'))
+ return c - ('a'-'A');
+ else
+ return c;
+}
+
+static int nocaseequal(char c1, char c2){
+ return upcase(c1)==upcase(c2);
+}
+
+static int strcasecmp(const char *s1, const char *s2){
+ int i;
+ for ( i=0; s1[i]!=0 && s2[i]!=0; i++){
+ if ( !nocaseequal(s1[i],s2[i]) ){
+ if (s1[i]<s2[i]){
+ return -1;
+ }else{
+ return 1;
+ }
+ }
+ }
+ if (s2[i]!=0){
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+MediaStream::MediaStream( MRef<Media *> media ):media(media),ka(NULL) {
+ disabled = false;
+#ifdef ZRTP_SUPPORT
+ zrtpBridge = NULL;
+#endif
+}
+
+std::string MediaStream::getSdpMediaType(){
+ if( media ){
+ return media->getSdpMediaType();
+ }
+ return "";
+}
+
+list<string> MediaStream::getSdpAttributes(){
+ return media->getSdpAttributes();
+}
+
+bool MediaStream::matches( MRef<SdpHeaderM *> m, uint32_t formatIndex ){
+ string sdpRtpMap;
+ string sdpFmtpParam;
+
+ // int i;
+ uint8_t sdpPayloadType = (uint8_t) m->getFormat( formatIndex );
+
+ media->handleMHeader( m );
+
+ // pn507 This checks for "Audio"
+ if( m->getMedia() != getSdpMediaType() ){
+ return false;
+ }
+
+ sdpRtpMap = m->getRtpMap( sdpPayloadType );
+ sdpFmtpParam = m->getFmtpParam( sdpPayloadType );
+
+ std::list<MRef<Codec *> > codecs = media->getAvailableCodecs();
+ std::list<MRef<Codec *> >::iterator iC;
+ string codecRtpMap;
+ uint8_t codecPayloadType;
+
+ size_t s1;
+ size_t s2 = sdpRtpMap.find("/");
+
+ for( iC = codecs.begin(); iC != codecs.end(); iC ++ ){
+ codecRtpMap = (*iC)->getSdpMediaAttributes();
+ codecPayloadType = (*iC)->getSdpMediaType();
+ if( (*iC)->getCodecName() == "iLBC" ) {
+ if( sdpFmtpParam != "mode=20" ) { //iLBC only supports 20ms frames (in minisip)
+ continue;
+ } //else ... does not mean we accept it, it still goes through the normal checks ...
+ }
+ if( sdpRtpMap != "" && codecRtpMap != "" ){
+ s1 = codecRtpMap.find("/");
+ bool sdpRtpMapEqual = !strcasecmp( codecRtpMap.substr(0, s1).c_str(), sdpRtpMap.substr(0,s2).c_str() );
+ if ( sdpRtpMapEqual ) {
+ localPayloadType = codecPayloadType;
+ return true;
+ }
+ else {
+ continue;
+ }
+
+ }
+ else{
+ if( sdpPayloadType == codecPayloadType ){
+ localPayloadType = codecPayloadType;
+ return true;
+ }else{
+ }
+ }
+ }
+ return false;
+}
+
+MRef<CryptoContext *> MediaStream::initCrypto( uint32_t ssrc, uint16_t seq_no ){
+ MRef<CryptoContext *> cryptoContext;
+
+ kaLock.lock();
+ if( !ka ){
+ /* Dummy cryptocontext */
+ cryptoContext = new CryptoContext( ssrc );
+ }
+ else {
+
+ unsigned char * masterKey = new unsigned char[16];
+ unsigned char * masterSalt = new unsigned char[14];
+
+ uint8_t csId = ka->getSrtpCsId( ssrc );
+ uint32_t roc = ka->getSrtpRoc( ssrc );
+ uint8_t policyNo = ka->findpolicyNo( ssrc );
+ //Extract Srtp policy !!! Check the return value if type not available
+ uint8_t ealg = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_EALG);
+ uint8_t ekeyl = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_EKEYL);
+ uint8_t aalg = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AALG);
+ uint8_t akeyl = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AKEYL);
+ uint8_t skeyl = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_SALTKEYL);
+ //uint8_t prf = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_PRF); //Not used
+ uint8_t keydr = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_KEY_DERRATE);
+ uint8_t encr = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_ENCR_ON_OFF);
+ //uint8_t cencr = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTCP_ENCR_ON_OFF);//Not used
+ //uint8_t fecor = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_FEC_ORDER); //Not used
+ uint8_t auth = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AUTH_ON_OFF);
+ uint8_t autht = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_AUTH_TAGL);
+ //uint8_t prefi = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_SRTP, MIKEY_SRTP_PREFIX); //Not used
+
+ ka->genTek( csId, masterKey, 16 );
+ ka->genSalt( csId, masterSalt, 14 );
+
+#ifdef DEBUG_OUTPUT
+#if 0
+ fprintf( stderr, "csId: %i\n", csId );
+ cerr << "SSRC: "<< ssrc <<" - TEK: " << print_hex( masterKey, 16 ) << endl;
+ cerr << "SSRC: "<< ssrc <<" - SALT: " << print_hex( masterSalt, 14 )<< endl;
+#endif
+#endif
+
+ if( csId != 0 ){
+ cryptoContext = new CryptoContext( ssrc, roc, seq_no, keydr,
+ ealg, aalg, masterKey, 16, masterSalt, 14, ekeyl, akeyl, skeyl, encr, auth, autht );
+
+ cryptoContext->derive_srtp_keys( 0 );
+ }
+ else{
+ cryptoContext = new CryptoContext( ssrc );
+ }
+ }
+
+ cryptoContexts.push_back( cryptoContext );
+ kaLock.unlock();
+ return cryptoContext;
+}
+
+MRef<CryptoContext *> MediaStream::getCryptoContext( uint32_t ssrc, uint16_t seq_no ){
+ kaLock.lock();
+ list< MRef<CryptoContext *> >::iterator i;
+
+ for( i = cryptoContexts.begin(); i!= cryptoContexts.end(); i++ ){
+ if( (*i)->getSsrc() == ssrc ){
+ kaLock.unlock();
+ return (*i);
+ }
+ }
+
+ kaLock.unlock();
+ return initCrypto( ssrc, seq_no );
+}
+
+void MediaStream::setKeyAgreement( MRef<KeyAgreement *> ka ){
+ kaLock.lock();
+ this->ka = ka;
+
+ /* Reset the CryptoContext since we have a new KeyAgreement */
+ cryptoContexts.clear();
+
+ kaLock.unlock();
+}
+
+#ifdef ZRTP_SUPPORT
+/*
+ * The ZRTP implementation (host bridge) calls this to register a new
+ * crypto context context for either the receiver or the sender of
+ * a receiver / sender. Keep in mind that we may have several senders
+ * for one receiver, that is one receiver can handle different
+ * incomming RTP sessions, they are identified by the SSRC. A sender
+ * handles one stream (media stream) to the remote peer only.
+ */
+void MediaStream::setKeyAgreementZrtp(MRef<CryptoContext *>cx) {
+
+ kaLock.lock();
+
+ list< MRef<CryptoContext *> >::iterator i;
+
+ for( i = cryptoContexts.begin(); i!= cryptoContexts.end(); i++ ){
+ if( (*i)->getSsrc() == cx->getSsrc() ) {
+ cryptoContexts.erase(i);
+ break;
+ }
+ }
+ cryptoContexts.push_back(cx);
+
+ kaLock.unlock();
+}
+#endif
+
+MediaStreamReceiver::MediaStreamReceiver( MRef<Media *> media,
+ MRef<RtpReceiver *> rtpReceiver, MRef<IpProvider *> ipProvider ):
+ MediaStream( media ),
+ rtpReceiver( rtpReceiver ),
+ ipProvider( ipProvider ){
+ id = rand();
+ externalPort = 0;
+ running = false;
+ codecList = media->getAvailableCodecs();
+}
+
+uint32_t MediaStreamReceiver::getId(){
+ return id;
+}
+
+void MediaStreamReceiver::start(){
+ if( !running ){
+ rtpReceiver->registerMediaStream( this );
+ running = true;
+ }
+}
+
+void MediaStreamReceiver::stop(){
+ list<uint32_t>::iterator i;
+ rtpReceiver->unregisterMediaStream( this );
+
+ ssrcListLock.lock();
+ for( i = ssrcList.begin(); i != ssrcList.end(); i++ ){
+ media->unRegisterMediaSource( *i );
+ }
+ ssrcList.clear();
+ ssrcListLock.unlock();
+
+ running = false;
+}
+
+uint16_t MediaStreamReceiver::getPort(){
+ return rtpReceiver->getPort();
+}
+
+#ifdef ZRTP_SUPPORT
+void MediaStreamReceiver::handleRtpPacketExt(MRef<SRtpPacket *> packet) {
+ uint32_t packetSsrc;
+ uint16_t seq_no;
+
+ //if packet is null, we had a read timeout from the rtpReceiver
+ if( !packet ) {
+ return;
+ }
+ packetSsrc = packet->getHeader().getSSRC();
+ seq_no = packet->getHeader().getSeqNo();
+
+ if( packet->unprotect( getCryptoContext( packetSsrc, seq_no ) )){
+ // Authentication or replay protection failed
+ return;
+ }
+ zrtpBridge->processPacket(packet);
+}
+#endif
+
+void MediaStreamReceiver::handleRtpPacket( MRef<SRtpPacket *> packet, MRef<IPAddress *> from ){
+ uint32_t packetSsrc;
+ uint16_t seq_no;
+
+ //if packet is null, we had a read timeout from the rtpReceiver
+ if( !packet ) {
+ return;
+ }
+
+ packetSsrc = packet->getHeader().getSSRC();
+ seq_no = packet->getHeader().getSeqNo();
+
+#ifdef ZRT_SUPPORT
+ /*
+ * Check if ZRTP shall handle the packet first. This will be done
+ * if the packet contains an extension header and our hostbridge's
+ * remote address matches the from address (sender address). If all
+ * holds true we also set the SSRC in the host bridge if it was zero
+ * before.
+ */
+ if (zrtpBridge && zrtpBridge->isSecureStateReceiver()) {
+ /*
+ * Check if this packet belongs to this receiver. To do so
+ * compare the from IP address with my known remote address
+ * stored in zrtpBridge.
+ */
+ if (zrtpBridge->getRemoteAddress() &&
+ zrtpBridge->getRemoteAddress() == from) {
+
+ /*
+ * If this is the first received packet of this session store
+ * the SSRC. Any later modification of the SSRC inside this session
+ * gives an Alert and switsches back to non-secure mode
+ */
+ if (zrtpBridge->getSsrcReceiver() == 0) {
+ zrtpBridge->setSsrcReceiver(packetSsrc);
+ }
+ if (zrtpBridge->getSsrcReceiver() != packetSsrc) {
+ zhb->rtpSessionError();
+ }
+ if( packet->unprotect( getCryptoContext( packetSsrc, seq_no ) )){
+ // Authentication or replay protection failed
+ return;
+ }
+ if (packet->getHeader()->getExtension()) {
+ if (zrtpBridge->processPacket(packet) == 0) {
+ return;
+ }
+ }
+ }
+ }
+ else {
+ if( packet->unprotect( getCryptoContext( packetSsrc, seq_no ) )){
+ // Authentication or replay protection failed
+ return;
+ }
+ }
+#else
+ if( packet->unprotect( getCryptoContext( packetSsrc, seq_no ) )){
+ // Authentication or replay protection failed
+ return;
+ }
+
+#endif // ZRTP_SUPPORT
+
+ //uint16_t seqNo = packet->getHeader().getSeqNo(); //not used
+ //byte_t * data = packet->getContent(); //not used
+ //uint32_t size = packet->getContentLength(); //not used
+ //bool marker = packet->getHeader().getMarker(); //not used
+ //uint32_t ts = packet->getHeader().getTimestamp(); //not used
+
+ gotSsrc( packetSsrc );
+
+ media->playData( *packet );
+}
+
+void MediaStreamReceiver::gotSsrc( uint32_t ssrc ){
+ list<uint32_t>::iterator i;
+
+ ssrcListLock.lock();
+ for( i = ssrcList.begin(); i != ssrcList.end(); i++ ){
+ if( (*i) == ssrc ){
+ ssrcListLock.unlock();
+ return;
+ }
+ }
+
+ media->registerMediaSource( ssrc );
+ ssrcList.push_back( ssrc );
+ ssrcListLock.unlock();
+}
+
+std::list<MRef<Codec *> > MediaStreamReceiver::getAvailableCodecs(){
+ return codecList;
+}
+
+MediaStreamSender::MediaStreamSender( MRef<Media *> media, MRef<UDPSocket *> senderSocket ):
+ MediaStream( media ){
+ selectedCodec = NULL;
+ remotePort = 0;
+ seqNo = (uint16_t)rand();
+ ssrc = rand();
+ lastTs = rand();
+ payloadType = 255;
+ setMuted( true );
+ muteCounter = 0;
+ if( senderSocket ){
+ this->senderSock = senderSocket;
+ }
+ else{
+ senderSock = new UDPSocket;
+ senderSock->setLowDelay();
+ }
+#ifdef ZRTP_SUPPORT
+ if (zrtpBridge) {
+ zrtpBridge->setSsrcSender(ssrc);
+ }
+#endif
+}
+
+void MediaStreamSender::start(){
+ media->registerMediaSender( this );
+#ifdef ZRTP_SUPPORT
+ if (zrtpBridge) {
+ zrtpBridge->start();
+ }
+#endif
+}
+
+void MediaStreamSender::stop(){
+ media->unRegisterMediaSender( this );
+#ifdef ZRTP_SUPPORT
+ if (zrtpBridge) {
+ zrtpBridge->stop();
+ }
+#endif
+}
+
+void MediaStreamSender::setPort( uint16_t port ){
+ remotePort = port;
+}
+
+uint16_t MediaStreamSender::getPort(){
+ return remotePort;
+}
+
+static bool first=true;
+
+#ifdef ZRTP_SUPPORT
+void MediaStreamSender::sendZrtp(unsigned char* data, int length,
+ unsigned char* payload, int payLen) {
+
+ if (this->remoteAddress.isNull()) {
+ mdbg << " MediaStreamSender::sendZrtp called before " <<
+ "setRemoteAddress!" << endl;
+ return;
+ }
+
+ SRtpPacket * packet;
+ if (first){
+#ifdef ENABLE_TS
+ ts.save("rtp_send");
+#endif
+ first=false;
+ }
+
+ senderLock.lock();
+ uint32_t ts = time(NULL);
+ packet = new SRtpPacket(payload, payLen, seqNo++, ts, ssrc );
+ packet->getHeader().setPayloadType(13);
+ packet->setExtHeader(data, length);
+
+ packet->protect(getCryptoContext(ssrc, seqNo - 1));
+
+ packet->sendTo( **senderSock, **remoteAddress, remotePort );
+ delete packet;
+ senderLock.unlock();
+
+}
+#endif // ZRTP_SUPPORT
+
+void MediaStreamSender::send( byte_t * data, uint32_t length, uint32_t * givenTs, bool marker, bool dtmf ){
+ if (this->remoteAddress.isNull()) {
+ mdbg << " MediaStreamSender::send called before " <<
+ "setRemoteAddress!" << endl;
+ return;
+ }
+ SRtpPacket * packet;
+ if (first){
+#ifdef ENABLE_TS
+ ts.save("rtp_send");
+#endif
+ first=false;
+ }
+
+ senderLock.lock();
+ if( !(*givenTs) ){
+ //FIXME! get it from the CODEC,
+ // when we have one CODEC per sender
+ increaseLastTs(); //increase lastTs ...
+ //lastTs += 160;
+ *givenTs = lastTs;
+ }
+ else{
+ lastTs = *givenTs;
+ }
+
+ packet = new SRtpPacket( data, length, seqNo++, lastTs, ssrc );
+
+ if( dtmf ){
+ packet->getHeader().setPayloadType( 101 );
+ }
+ else{
+ if( payloadType != 255 )
+ packet->getHeader().setPayloadType( payloadType );
+ else
+ packet->getHeader().setPayloadType( selectedCodec->getSdpMediaType() );
+ }
+
+ if( marker ){
+ packet->getHeader().setMarker( marker );
+ }
+
+ packet->protect( getCryptoContext( ssrc, seqNo - 1 ) );
+
+ packet->sendTo( **senderSock, **remoteAddress, remotePort );
+ delete packet;
+ senderLock.unlock();
+}
+
+void MediaStreamSender::setRemoteAddress( MRef<IPAddress *> remoteAddress ){
+ mdbg << "MediaStreamSender::setRemoteAddress: " <<
+ remoteAddress->getString() << endl;
+ this->remoteAddress = remoteAddress;
+#ifdef ZRTP_SUPPORT
+ if (zrtpBridge) {
+ zrtpBridge->setRemoteAddress(remoteAddress);
+ }
+#endif // ZRTP_SUPPORT
+}
+
+#ifdef DEBUG_OUTPUT
+string MediaStream::getDebugString() {
+ string ret;
+ ret = getMemObjectType() + " this=" + itoa((int64_t)this) +
+ ": port=" + itoa(getPort());
+
+ return ret;
+}
+string MediaStreamReceiver::getDebugString() {
+ string ret;
+ ret = getMemObjectType() + " this=" + itoa((int64_t)this) +
+ ": listening port=" + itoa(rtpReceiver->getPort());
+ for( std::list<uint32_t>::iterator it = ssrcList.begin();
+ it != ssrcList.end();
+ it++) {
+ "; ssrc=" + itoa((*it));
+ }
+ return ret;
+}
+string MediaStreamSender::getDebugString() {
+ string ret;
+
+ ret = getMemObjectType() + " this=" + itoa((int64_t)this) +
+ ": port=" + itoa(getPort()) +
+ "; remotePort=" + itoa(remotePort);
+
+ if( isMuted() == true )
+ ret += "; isMuted=true";
+ else ret += "; isMuted=false";
+
+ return ret;
+}
+#endif
+
+//keep a counter, so we can send a keep alive
+//packet every now and then.
+//Max indicates every how many silenced packets we send one keep-alive
+//It returns true if the packet needs to be let through, false otherwise
+bool MediaStreamSender::muteKeepAlive( uint32_t max ) {
+ bool ret = false;
+
+ //if muted, only return true if packet is keep alive
+ if( isMuted() ) {
+ muteCounter++;
+ if( muteCounter >= max ) {
+ ret = true;
+ muteCounter = 0;
+ }
+ } else {
+ //if active sender, let through
+ ret = true;
+ }
+ return ret;
+}
+
+bool MediaStreamSender::matches( MRef<SdpHeaderM *> m, uint32_t formatIndex ){
+ bool result = MediaStream::matches( m, formatIndex );
+
+ if( result && !selectedCodec ){
+ selectedCodec = media->createCodecInstance(
+ localPayloadType );
+ payloadType = (uint8_t)m->getFormat( formatIndex );
+ }
+
+ return result;
+}
+
+uint32_t MediaStreamSender::getSsrc(){
+ return ssrc;
+}
Modified: trunk/libminisip/source/mediahandler/RtpReceiver.cxx
===================================================================
--- trunk/libminisip/source/mediahandler/RtpReceiver.cxx 2006-06-04 08:07:43 UTC (rev 2612)
+++ trunk/libminisip/source/mediahandler/RtpReceiver.cxx 2006-06-04 08:08:03 UTC (rev 2613)
@@ -1,255 +1,295 @@
-/*
- Copyright (C) 2004-2006 the Minisip Team
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Copyright (C) 2004, 2005
- *
- * Authors: Erik Eliasson <eliasson at it.kth.se>
- * Johan Bilien <jobi at via.ecp.fr>
-*/
-
-#include <config.h>
-
-#include<libminisip/mediahandler/RtpReceiver.h>
-
-#include<libmnetutil/UDPSocket.h>
-#include<libmnetutil/NetworkException.h>
-#include<libmutil/Thread.h>
-
-#include<libminisip/rtp/SRtpPacket.h>
-#include<libminisip/codecs/Codec.h>
-#include<iostream>
-#include<libminisip/mediahandler/MediaStream.h>
-#include<libminisip/ipprovider/IpProvider.h>
-
-#include<libmutil/itoa.h> //for debug ... remove ... cesc
-
-#include<stdio.h>
-#include<sys/types.h>
-#include<stdlib.h> //for rand
-
-#ifdef WIN32
-#include<winsock2.h>
-#endif
-
-#ifdef _MSC_VER
-
-#else
-#include<sys/time.h>
-#include<unistd.h>
-#include<errno.h>
-#endif
-
-#ifdef _WIN32_WCE
-# include"../include/minisip_wce_extra_includes.h"
-#endif
-
-//Set the range of rtp usable ports ... starting at min and spanning a range, up to max
-#define RTP_LOCAL_PORT_RANGE_MIN 30000
-#define RTP_LOCAL_PORT_RANGE 5000
-#define RTP_LOCAL_PORT_RANGE_MAX RTP_LOCAL_PORT_RANGE_MIN + RTP_LOCAL_PORT_RANGE
-#define RTP_RECEIVER_MAX_RETRIES 5
-
-
-using namespace std;
-
-RtpReceiver::RtpReceiver( MRef<IpProvider *> ipProvider){
-
- socket = NULL;
-
- int portretry = 0;
- for (; portretry<RTP_RECEIVER_MAX_RETRIES; portretry++ ) {
- //generate a random port, even number, in the given range
- float randPartial = (float)rand() / RAND_MAX;
- int port = (int) (RTP_LOCAL_PORT_RANGE * randPartial );
- port = (int) ( 2 * (int)(port/2 ) ); //turn this into an even number
- port += RTP_LOCAL_PORT_RANGE_MIN; //add the min port to set it within the range
- #ifdef DEBUG_OUTPUT
- printf( "RtpReceiver:: final trying port = %d\n", port );
- #endif
- try{
- socket = new UDPSocket( port );
- if( socket ) {
- break;
- }
- }
- catch( NetworkException & ){
- // FIXME: do something nice
-// merr << "Minisip could not create a UDP socket!" << end;
-// merr << "Check your network settings." << end;
-// exit( 1 );
- #ifdef DEBUG_OUTPUT
- cerr << "RtpReceiver: Could not create UDP socket" << endl;
- #endif
- }
- }
- if( portretry == RTP_RECEIVER_MAX_RETRIES && !socket ) {
- merr << "Minisip could not create a UDP socket!" << end;
- merr << "Check your network settings." << end << "Quitting badly" << end;
- exit( 1 );
- }
-
- externalPort = ipProvider->getExternalPort( socket );
-
- kill = false;
-
- thread = new Thread(this);
-}
-
-RtpReceiver::~RtpReceiver(){
- thread->join();
- delete thread;
- socket->close();
-}
-
-/**
- register a mediaStreamReceiver ... if the receiver is already registered,
- update the exhisting one to point to the new receiver.
-*/
-void RtpReceiver::registerMediaStream( MRef<MediaStreamReceiver *> mediaStream ){
- list< MRef<MediaStreamReceiver *> >::iterator iter;
- mediaStreamsLock.lock();
- /* Don't register new streams if the receiver is being closed */
- if( !kill ){
- bool found = false;
- //cerr << "RtpReceiver::registerMediaStream: register done!" << endl;
- for( iter = mediaStreams.begin();
- iter != mediaStreams.end();
- iter++ ) {
- if( (*iter)->getId() == mediaStream->getId() ) {
- found = true;
- #ifdef DEBUG_OUTPUT
- cerr << "RtpRcvr::registerMediaStream: media stream already registered. Updating MRef." << endl;
- #endif
- (*iter) = mediaStream;
- break;
- }
- }
- if( !found ) {
- mediaStreams.push_back( mediaStream );
- }
- }
- mediaStreamsLock.unlock();
-}
-
-void RtpReceiver::unregisterMediaStream( MRef<MediaStreamReceiver *> mediaStream ){
-#ifdef DEBUG_OUTPUT
- // cerr << "RtpReceiver::unregisterMediaStream: Before taking lock" << endl;
-#endif
- mediaStreamsLock.lock();
- mediaStreams.remove( mediaStream );
- if( mediaStreams.size() == 0 ){
- /* End the thread */
- kill = true;
- }
- mediaStreamsLock.unlock();
-#ifdef DEBUG_OUTPUT
- // cerr << "RtpReceiver::unregisterMediaStream: After taking lock" << endl;
-#endif
-}
-
-uint16_t RtpReceiver::getPort(){
- return externalPort;
-}
-
-MRef<UDPSocket *> RtpReceiver::getSocket(){
- return socket;
-}
-
-void RtpReceiver::run(){
- MRef<SRtpPacket *> packet;
-
- while( !kill ){
- list< MRef<MediaStreamReceiver *> >::iterator i;
- fd_set rfds;
- struct timeval tv;
- int ret = -1;
-
- FD_ZERO( &rfds );
- #ifdef WIN32
- FD_SET( (uint32_t) socket->getFd(), &rfds );
- #else
- FD_SET( socket->getFd(), &rfds );
- #endif
-
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
-
- while( ret < 0 ){
- ret = select( socket->getFd() + 1, &rfds, NULL, NULL, &tv );
- if( ret < 0 ){
- #ifdef DEBUG_OUTPUT
- //FIXME: do something better
- cerr << "RtpReceiver::run() - select returned -1" << endl;
- #endif
-
- #ifndef _WIN32_WCE
- if( errno == EINTR ) { continue; }
- #else
- if( errno == WSAEINTR ) { continue; }
- #endif
- else {
- kill = true;
- break;
- }
- }
- }
-
- if( kill ) {
- break;
- }
-
- if( ret == 0 /* timeout */ ){
- //notify the mediaStreams of the timeout
- for( i = mediaStreams.begin();
- i != mediaStreams.end(); i++ ){
- (*i)->handleRtpPacket( NULL );
- }
- continue;
- }
-
- try{
- packet = SRtpPacket::readPacket( **socket );
- }
-
- catch (NetworkException & ){
- continue;
- }
-
- if( !packet ){
- continue;
- }
-
- mediaStreamsLock.lock();
- for( i = mediaStreams.begin(); i != mediaStreams.end(); i++ ){
- std::list<MRef<Codec *> > codecs = (*i)->getAvailableCodecs();
- std::list<MRef<Codec *> >::iterator iC;
- //printf( "|" );
- for( iC = codecs.begin(); iC != codecs.end(); iC ++ ){
- if ( (*iC)->getSdpMediaType() == packet->getHeader().getPayloadType() ) {
- (*i)->handleRtpPacket( packet );
- //printf( "~" );
- break;
- }
- }
- }
-
- mediaStreamsLock.unlock();
-
- packet = NULL;
- }
-}
+/*
+ Copyright (C) 2004-2006 the Minisip Team
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Copyright (C) 2004, 2005
+ *
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ * Johan Bilien <jobi at via.ecp.fr>
+*/
+
+#include <config.h>
+
+#include<libminisip/mediahandler/RtpReceiver.h>
+
+#include<libmnetutil/UDPSocket.h>
+#include<libmnetutil/NetworkException.h>
+#include<libmutil/Thread.h>
+
+#include<libminisip/rtp/SRtpPacket.h>
+#include<libminisip/codecs/Codec.h>
+#include<iostream>
+#include<libminisip/mediahandler/MediaStream.h>
+#include<libminisip/ipprovider/IpProvider.h>
+
+#include<libmutil/itoa.h> //for debug ... remove ... cesc
+
+#include<stdio.h>
+#include<sys/types.h>
+#include<stdlib.h> //for rand
+
+#ifdef WIN32
+#include<winsock2.h>
+#endif
+
+#ifdef _MSC_VER
+
+#else
+#include<sys/time.h>
+#include<unistd.h>
+#include<errno.h>
+#endif
+
+#ifdef _WIN32_WCE
+# include"../include/minisip_wce_extra_includes.h"
+#endif
+
+//Set the range of rtp usable ports ... starting at min and spanning a range, up to max
+#define RTP_LOCAL_PORT_RANGE_MIN 30000
+#define RTP_LOCAL_PORT_RANGE 5000
+#define RTP_LOCAL_PORT_RANGE_MAX RTP_LOCAL_PORT_RANGE_MIN + RTP_LOCAL_PORT_RANGE
+#define RTP_RECEIVER_MAX_RETRIES 5
+
+
+using namespace std;
+
+RtpReceiver::RtpReceiver( MRef<IpProvider *> ipProvider){
+
+ socket = NULL;
+
+ int portretry = 0;
+ for (; portretry<RTP_RECEIVER_MAX_RETRIES; portretry++ ) {
+ //generate a random port, even number, in the given range
+ float randPartial = (float)rand() / RAND_MAX;
+ int port = (int) (RTP_LOCAL_PORT_RANGE * randPartial );
+ port = (int) ( 2 * (int)(port/2 ) ); //turn this into an even number
+ port += RTP_LOCAL_PORT_RANGE_MIN; //add the min port to set it within the range
+ #ifdef DEBUG_OUTPUT
+ printf( "RtpReceiver:: final trying port = %d\n", port );
+ #endif
+ try{
+ socket = new UDPSocket( port );
+ if( socket ) {
+ break;
+ }
+ }
+ catch( NetworkException & ){
+ // FIXME: do something nice
+// merr << "Minisip could not create a UDP socket!" << end;
+// merr << "Check your network settings." << end;
+// exit( 1 );
+ #ifdef DEBUG_OUTPUT
+ cerr << "RtpReceiver: Could not create UDP socket" << endl;
+ #endif
+ }
+ }
+ if( portretry == RTP_RECEIVER_MAX_RETRIES && !socket ) {
+ merr << "Minisip could not create a UDP socket!" << end;
+ merr << "Check your network settings." << end << "Quitting badly" << end;
+ exit( 1 );
+ }
+
+ externalPort = ipProvider->getExternalPort( socket );
+
+ kill = false;
+
+ thread = new Thread(this);
+}
+
+RtpReceiver::~RtpReceiver(){
+ thread->join();
+ delete thread;
+ socket->close();
+}
+
+/**
+ register a mediaStreamReceiver ... if the receiver is already registered,
+ update the exhisting one to point to the new receiver.
+*/
+void RtpReceiver::registerMediaStream( MRef<MediaStreamReceiver *> mediaStream ){
+ list< MRef<MediaStreamReceiver *> >::iterator iter;
+ mediaStreamsLock.lock();
+ /* Don't register new streams if the receiver is being closed */
+ if( !kill ){
+ bool found = false;
+ //cerr << "RtpReceiver::registerMediaStream: register done!" << endl;
+ for( iter = mediaStreams.begin();
+ iter != mediaStreams.end();
+ iter++ ) {
+ if( (*iter)->getId() == mediaStream->getId() ) {
+ found = true;
+ #ifdef DEBUG_OUTPUT
+ cerr << "RtpRcvr::registerMediaStream: media stream already registered. Updating MRef." << endl;
+ #endif
+ (*iter) = mediaStream;
+ break;
+ }
+ }
+ if( !found ) {
+ mediaStreams.push_back( mediaStream );
+ }
+ }
+ mediaStreamsLock.unlock();
+}
+
+void RtpReceiver::unregisterMediaStream( MRef<MediaStreamReceiver *> mediaStream ){
+#ifdef DEBUG_OUTPUT
+ // cerr << "RtpReceiver::unregisterMediaStream: Before taking lock" << endl;
+#endif
+ mediaStreamsLock.lock();
+ mediaStreams.remove( mediaStream );
+ if( mediaStreams.size() == 0 ){
+ /* End the thread */
+ kill = true;
+ }
+ mediaStreamsLock.unlock();
+#ifdef DEBUG_OUTPUT
+ // cerr << "RtpReceiver::unregisterMediaStream: After taking lock" << endl;
+#endif
+}
+
+uint16_t RtpReceiver::getPort(){
+ return externalPort;
+}
+
+MRef<UDPSocket *> RtpReceiver::getSocket(){
+ return socket;
+}
+
+void RtpReceiver::run(){
+ MRef<SRtpPacket *> packet;
+
+ while( !kill ){
+ list< MRef<MediaStreamReceiver *> >::iterator i;
+ fd_set rfds;
+ struct timeval tv;
+ int ret = -1;
+
+ FD_ZERO( &rfds );
+ #ifdef WIN32
+ FD_SET( (uint32_t) socket->getFd(), &rfds );
+ #else
+ FD_SET( socket->getFd(), &rfds );
+ #endif
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000;
+
+ while( ret < 0 ){
+ ret = select( socket->getFd() + 1, &rfds, NULL, NULL, &tv );
+ if( ret < 0 ){
+ #ifdef DEBUG_OUTPUT
+ //FIXME: do something better
+ cerr << "RtpReceiver::run() - select returned -1" << endl;
+ #endif
+
+ #ifndef _WIN32_WCE
+ if( errno == EINTR ) { continue; }
+ #else
+ if( errno == WSAEINTR ) { continue; }
+ #endif
+ else {
+ kill = true;
+ break;
+ }
+ }
+ }
+
+ if( kill ) {
+ break;
+ }
+
+ if( ret == 0 /* timeout */ ){
+ //notify the mediaStreams of the timeout
+ for( i = mediaStreams.begin();
+ i != mediaStreams.end(); i++ ){
+ (*i)->handleRtpPacket( NULL, NULL );
+ }
+ continue;
+ }
+ MRef<IPAddress *> from = NULL;
+ try{
+ packet = SRtpPacket::readPacket( **socket, from);
+ }
+
+ catch (NetworkException & ){
+ continue;
+ }
+
+ if( !packet ){
+ continue;
+ }
+
+ mediaStreamsLock.lock();
+ for( i = mediaStreams.begin(); i != mediaStreams.end(); i++ ){
+ std::list<MRef<Codec *> > codecs = (*i)->getAvailableCodecs();
+ std::list<MRef<Codec *> >::iterator iC;
+ int found = 0;
+ //printf( "|" );
+ for( iC = codecs.begin(); iC != codecs.end(); iC ++ ){
+ if ( (*iC)->getSdpMediaType() == packet->getHeader().getPayloadType() ) {
+ (*i)->handleRtpPacket( packet, from );
+ found = 1;
+ //printf( "~" );
+ break;
+ }
+ }
+#ifdef ZRTP_SUPPORT
+ /*
+ * If this packet was not already handled
+ * (!found) and it has an extension header and
+ * it belongs to this media pair's (receiver
+ * and sender) remote address then handle it
+ * accordingly in the ZrtpHostBridge.
+ *
+ * TODO: handle list of host bridges because a
+ * receiver may support several RTP sessions
+ * from different peers.
+ */
+ MRef<ZrtpHostBridgeMinisip *>zhb = (*i)->getZrtpHostBridge();
+
+ if (!found && zhb && packet->getHeader().getExtension() &&
+ zhb->getRemoteAddress() && zhb->getRemoteAddress() == from) {
+
+ uint32_t packetSsrc = packet->getHeader().getSSRC();
+
+ /*
+ * If this is the first received packet of
+ * this session then store its SSRC. Any
+ * later modification of the SSRC inside
+ * this session gives an Alert and
+ * switsches back to non-secure mode
+ */
+
+ if (zhb->getSsrcReceiver() == 0) {
+ zhb->setSsrcReceiver(packetSsrc);
+ }
+ if (zhb->getSsrcReceiver() != packetSsrc) {
+ zhb->rtpSessionError();
+ }
+ else {
+ (*i)->handleRtpPacketExt(packet);
+ }
+ }
+#endif // ZRTP_SUPPORT
+ }
+
+ mediaStreamsLock.unlock();
+
+ packet = NULL;
+ }
+}
More information about the Minisip-devel
mailing list