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