Commit c6282441 authored by Tristan Matthews's avatar Tristan Matthews

* #9641: get rid of getType/RtpMethod logic

parent 4f774530
......@@ -43,9 +43,9 @@
namespace sfl {
AudioRtpFactory::AudioRtpFactory(SIPCall *ca) : rtpSession_(NULL),
audioRtpThreadMutex_(), srtpEnabled_(false),
keyExchangeProtocol_(Symmetric), helloHashEnabled_(false),
remoteContext_(NULL), localContext_(NULL), ca_(ca)
audioRtpThreadMutex_(), srtpEnabled_(false), helloHashEnabled_(false),
remoteContext_(NULL), localContext_(NULL), ca_(ca),
keyExchangeProtocol_(NONE)
{}
AudioRtpFactory::~AudioRtpFactory()
......@@ -53,7 +53,7 @@ AudioRtpFactory::~AudioRtpFactory()
delete rtpSession_;
}
void AudioRtpFactory::initAudioRtpConfig()
void AudioRtpFactory::initConfig()
{
if (rtpSession_ != NULL)
stop();
......@@ -65,23 +65,23 @@ void AudioRtpFactory::initAudioRtpConfig()
if (account) {
srtpEnabled_ = account->getSrtpEnabled();
std::string key(account->getSrtpKeyExchange());
if (key == "sdes")
keyExchangeProtocol_ = Sdes;
else if (key == "zrtp")
keyExchangeProtocol_ = Zrtp;
else
keyExchangeProtocol_ = Symmetric;
if (srtpEnabled_) {
if (key == "sdes")
keyExchangeProtocol_ = SDES;
else if (key == "zrtp")
keyExchangeProtocol_ = ZRTP;
} else {
keyExchangeProtocol_ = NONE;
}
helloHashEnabled_ = account->getZrtpHelloHash();
} else {
srtpEnabled_ = false;
keyExchangeProtocol_ = Symmetric;
keyExchangeProtocol_ = NONE;
helloHashEnabled_ = false;
}
}
void AudioRtpFactory::initAudioSymmetricRtpSession()
void AudioRtpFactory::initSession()
{
ost::MutexLock m(audioRtpThreadMutex_);
......@@ -90,7 +90,7 @@ void AudioRtpFactory::initAudioSymmetricRtpSession()
switch (keyExchangeProtocol_) {
case Zrtp:
case ZRTP:
rtpSession_ = new AudioZrtpSession(ca_, zidFilename);
// TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's
// not even available at that point.
......@@ -98,7 +98,7 @@ void AudioRtpFactory::initAudioSymmetricRtpSession()
ca_->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(rtpSession_)->getHelloHash());
break;
case Sdes:
case SDES:
rtpSession_ = new AudioSrtpSession(ca_);
break;
......@@ -114,12 +114,11 @@ void AudioRtpFactory::start(AudioCodec* audiocodec)
if (rtpSession_ == NULL)
throw AudioRtpFactoryException("AudioRtpFactory: Error: RTP session was null when trying to start audio thread");
if (rtpSession_->getAudioRtpType() == Sdes)
if (localContext_ and remoteContext_)
static_cast<AudioSrtpSession *>(rtpSession_)->restoreCryptoContext(localContext_, remoteContext_);
if (keyExchangeProtocol_ == SDES and localContext_ and remoteContext_)
static_cast<AudioSrtpSession *>(rtpSession_)->restoreCryptoContext(localContext_, remoteContext_);
if (rtpSession_->startRtpThread(audiocodec) != 0)
throw AudioRtpFactoryException("AudioRtpFactory: Error: Failed to start AudioZrtpSession thread");
throw AudioRtpFactoryException("AudioRtpFactory: Error: Failed to start AudioRtpSession thread");
}
void AudioRtpFactory::stop()
......@@ -129,7 +128,7 @@ void AudioRtpFactory::stop()
if (rtpSession_ == NULL)
return;
if (rtpSession_->getAudioRtpType() == Sdes) {
if (keyExchangeProtocol_ == SDES) {
localContext_ = static_cast<AudioSrtpSession*>(rtpSession_)->localCryptoCtx_;
remoteContext_ = static_cast<AudioSrtpSession*>(rtpSession_)->remoteCryptoCtx_;
}
......@@ -162,7 +161,7 @@ void AudioRtpFactory::updateDestinationIpAddress()
sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
{
if (rtpSession_->getAudioRtpType() == Zrtp)
if (keyExchangeProtocol_ == ZRTP)
return static_cast<AudioZrtpSession *>(rtpSession_);
else
throw AudioRtpFactoryException("RTP: Error: rtpSession_ is NULL in getAudioZrtpSession");
......@@ -170,15 +169,16 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
void sfl::AudioRtpFactory::initLocalCryptoInfo()
{
if (rtpSession_ && rtpSession_->getAudioRtpType() == Sdes) {
static_cast<AudioSrtpSession *>(rtpSession_)->initLocalCryptoInfo();
ca_->getLocalSDP()->setLocalSdpCrypto(static_cast<AudioSrtpSession *>(rtpSession_)->getLocalCryptoInfo());
if (rtpSession_ && keyExchangeProtocol_ == SDES) {
AudioSrtpSession *srtpSession = static_cast<AudioSrtpSession*>(rtpSession_);
srtpSession->initLocalCryptoInfo();
ca_->getLocalSDP()->setLocalSdpCrypto(srtpSession->getLocalCryptoInfo());
}
}
void AudioRtpFactory::setRemoteCryptoInfo(sfl::SdesNegotiator& nego)
{
if (rtpSession_ && rtpSession_->getAudioRtpType() == Sdes)
if (rtpSession_ and keyExchangeProtocol_ == SDES)
static_cast<AudioSrtpSession *>(rtpSession_)->setRemoteCryptoInfo(nego);
else
throw AudioRtpFactoryException("RTP: Error: rtpSession_ is NULL in setRemoteCryptoInfo");
......
......@@ -62,15 +62,15 @@ class AudioRtpFactory {
AudioRtpFactory(SIPCall *ca);
~AudioRtpFactory();
void initAudioRtpConfig();
void initConfig();
/**
* Lazy instantiation method. Create a new RTP session of a given
* type according to the content of the configuration file.
* @param ca A pointer on a SIP call
* @return A new AudioSymmetricRtpSession object
* @return A new AudioRtpSession object
*/
void initAudioSymmetricRtpSession();
void initSession();
/**
* Start the audio rtp thread of the type specified in the configuration
......@@ -103,7 +103,7 @@ class AudioRtpFactory {
void updateDestinationIpAddress();
bool isSdesEnabled() const {
return srtpEnabled_ and keyExchangeProtocol_ == sfl::Sdes;
return srtpEnabled_ and keyExchangeProtocol_ == SDES;
}
/**
......@@ -140,17 +140,14 @@ class AudioRtpFactory {
private:
NON_COPYABLE(AudioRtpFactory);
enum KeyExchangeProtocol { NONE, SDES, ZRTP };
AudioRtpSession *rtpSession_;
ost::Mutex audioRtpThreadMutex_;
// Field used when initializinga udio rtp session
// Field used when initializing audio rtp session
// May be set manually or from config using initAudioRtpConfig
bool srtpEnabled_;
// Field used when initializinga udio rtp session
// May be set manually or from config using initAudioRtpConfig
RtpMethod keyExchangeProtocol_;
// Field used when initializinga udio rtp session
// May be set manually or from config using initAudioRtpConfig
bool helloHashEnabled_;
......@@ -162,6 +159,7 @@ class AudioRtpFactory {
ost::CryptoContext *localContext_;
SIPCall *ca_;
KeyExchangeProtocol keyExchangeProtocol_;
};
}
#endif // __AUDIO_RTP_FACTORY_H__
......@@ -43,17 +43,16 @@
#include "manager.h"
namespace sfl {
AudioRtpSession::AudioRtpSession(SIPCall * sipcall, RtpMethod type, ost::RTPDataQueue *queue, ost::Thread *thread) :
AudioRtpSession::AudioRtpSession(SIPCall * sipcall, ost::RTPDataQueue *queue, ost::Thread *thread) :
AudioRtpRecordHandler(sipcall)
, ca_(sipcall)
, type_(type)
, remote_ip_()
, remote_port_(0)
, timestamp_(0)
, timestampIncrement_(0)
, timestampCount_(0)
, isStarted_(false)
, queue_(queue)
, isStarted_(false)
, remote_ip_()
, remote_port_(0)
, timestampCount_(0)
, thread_(thread)
{
assert(ca_);
......@@ -96,26 +95,28 @@ void AudioRtpSession::setSessionMedia(AudioCodec *audioCodec)
else
timestampIncrement_ = frameSize;
DEBUG("AudioRptSession: Codec payload: %d", payloadType);
DEBUG("AudioSymmetricRtpSession: Codec sampling rate: %d", smplRate);
DEBUG("AudioSymmetricRtpSession: Codec frame size: %d", frameSize);
DEBUG("AudioSymmetricRtpSession: RTP timestamp increment: %d", timestampIncrement_);
DEBUG("AudioRtpSession: Codec payload: %d", payloadType);
DEBUG("AudioRtpSession: Codec sampling rate: %d", smplRate);
DEBUG("AudioRtpSession: Codec frame size: %d", frameSize);
DEBUG("AudioRtpSession: RTP timestamp increment: %d", timestampIncrement_);
if (payloadType == g722PayloadType) {
DEBUG("AudioSymmetricRtpSession: Setting G722 payload format");
DEBUG("AudioRtpSession: Setting G722 payload format");
queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, g722RtpClockRate));
} else {
if (dynamic) {
DEBUG("AudioSymmetricRtpSession: Setting dynamic payload format");
DEBUG("AudioRtpSession: Setting dynamic payload format");
queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, smplRate));
} else {
DEBUG("AudioSymmetricRtpSession: Setting static payload format");
DEBUG("AudioRtpSession: Setting static payload format");
queue_->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) payloadType));
}
}
}
if (type_ != Zrtp)
ca_->setRecordingSmplRate(getCodecSampleRate());
void AudioRtpSession::incrementTimestampForDTMF()
{
timestamp_ += timestampIncrement_;
}
void AudioRtpSession::sendDtmfEvent()
......@@ -131,7 +132,7 @@ void AudioRtpSession::sendDtmfEvent()
DEBUG("AudioRtpSession: Send RTP Dtmf (%d)", payload.event);
timestamp_ += (type_ == Zrtp) ? 160 : timestampIncrement_;
incrementTimestampForDTMF();
// discard equivalent size of audio
processDataEncode();
......@@ -166,22 +167,18 @@ void AudioRtpSession::receiveSpeakerData()
}
void AudioRtpSession::sendMicData()
{
int compSize = processDataEncode();
// if no data return
if (!compSize)
if (compSize == 0)
return;
// Increment timestamp for outgoing packet
timestamp_ += timestampIncrement_;
if (type_ == Zrtp)
queue_->putData(timestamp_, getMicDataEncoded(), compSize);
// putData put the data on RTP queue, sendImmediate bypass this queue
// putData puts the data on RTP queue, sendImmediate bypass this queue
queue_->sendImmediate(timestamp_, getMicDataEncoded(), compSize);
}
......@@ -238,7 +235,7 @@ int AudioRtpSession::startRtpThread(AudioCodec* audiocodec)
if (isStarted_)
return 0;
DEBUG("AudioSymmetricRtpSession: Starting main thread");
DEBUG("AudioRtpSession: Starting main thread");
isStarted_ = true;
setSessionTimeouts();
......@@ -247,14 +244,7 @@ int AudioRtpSession::startRtpThread(AudioCodec* audiocodec)
initNoiseSuppress();
queue_->enableStack();
int ret = thread_->start();
if (type_ == Zrtp)
return ret;
AudioSymmetricRtpSession *self = dynamic_cast<AudioSymmetricRtpSession*>(this);
assert(self);
return self->startSymmetricRtpThread();
return thread_->start();
}
......
......@@ -46,29 +46,18 @@ namespace sfl {
class AudioCodec;
// Possible kind of rtp session
typedef enum RtpMethod {
Symmetric,
Zrtp,
Sdes
} RtpMethod;
class AudioRtpSession : public AudioRtpRecordHandler {
public:
/**
* Constructor
* @param sipcall The pointer on the SIP call
*/
AudioRtpSession(SIPCall* sipcall, RtpMethod type, ost::RTPDataQueue *queue, ost::Thread *thread);
AudioRtpSession(SIPCall* sipcall, ost::RTPDataQueue *queue, ost::Thread *thread);
virtual ~AudioRtpSession();
RtpMethod getAudioRtpType() {
return type_;
}
void updateSessionMedia(AudioCodec *audioCodec);
int startRtpThread(AudioCodec*);
virtual int startRtpThread(AudioCodec*);
/**
* Used mostly when receiving a reinvite
......@@ -76,6 +65,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
void updateDestinationIpAddress();
protected:
/**
* Set the audio codec for this RTP session
*/
virtual void setSessionMedia(AudioCodec *codec) = 0;
bool onRTPPacketRecv(ost::IncomingRTPPkt&);
......@@ -90,19 +84,26 @@ class AudioRtpSession : public AudioRtpRecordHandler {
/**
* Send encoded data to peer
*/
void sendMicData();
virtual void sendMicData();
SIPCall *ca_;
RtpMethod type_;
private:
NON_COPYABLE(AudioRtpSession);
/**
* Timestamp for this session
*/
int timestamp_;
/**
* Set the audio codec for this RTP session
* Timestamp incrementation value based on codec period length (framesize)
* except for G722 which require a 8 kHz incrementation.
*/
void setSessionMedia(AudioCodec*);
int timestampIncrement_;
ost::RTPDataQueue *queue_;
bool isStarted_;
private:
NON_COPYABLE(AudioRtpSession);
/**
* Set RTP Sockets send/receive timeouts
......@@ -119,6 +120,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
*/
void receiveSpeakerData();
/**
* Increment timestamp for DTMF event
*/
virtual void incrementTimestampForDTMF();
// Main destination address for this rtp session.
// Stored in case or reINVITE, which may require to forget
// this destination and update a new one.
......@@ -129,26 +135,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
// this destination and update a new one
unsigned short remote_port_;
/**
* Timestamp for this session
*/
int timestamp_;
/**
* Timestamp incrementation value based on codec period length (framesize)
* except for G722 which require a 8 kHz incrementation.
*/
int timestampIncrement_;
/**
* Timestamp reset frequency specified in number of packet sent
*/
short timestampCount_;
bool isStarted_;
ost::RTPDataQueue *queue_;
ost::Thread *thread_;
};
......
......@@ -59,14 +59,7 @@ AudioSrtpSession::AudioSrtpSession(SIPCall * sipcall) :
remoteMasterSalt_(),
remoteMasterSaltLength_(0),
remoteOfferIsSet_(false)
{
type_ = Sdes;
}
AudioSrtpSession::~AudioSrtpSession()
{
DEBUG("AudioSrtp: Destroy audio srtp session");
}
{}
void AudioSrtpSession::initLocalCryptoInfo()
{
......@@ -326,4 +319,5 @@ char* AudioSrtpSession::decodeBase64(unsigned char *input, int length)
return buffer;
}
}
......@@ -75,8 +75,6 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
*/
AudioSrtpSession(SIPCall * sipcall);
~AudioSrtpSession();
/**
* Used to get sdp crypto header to be included in sdp session. This
* method must be called befor setRemoteCryptoInfo in case of an
......
......@@ -44,8 +44,7 @@ namespace sfl {
AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall * sipcall) :
ost::TimerPort()
, ost::SymmetricRTPSession(ost::InetHostAddress(sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort())
, AudioRtpSession(sipcall, Symmetric, this, this)
, echoCanceller()
, AudioRtpSession(sipcall, this, this)
, rtpThread_(new AudioRtpThread(this))
{
DEBUG("AudioSymmetricRtpSession: Setting new RTP session with destination %s:%d", ca_->getLocalIp().c_str(), ca_->getLocalAudioPort());
......@@ -54,12 +53,14 @@ AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall * sipcall) :
AudioSymmetricRtpSession::~AudioSymmetricRtpSession()
{
rtpThread_->running = false;
rtpThread_->running_ = false;
delete rtpThread_;
}
AudioSymmetricRtpSession::AudioRtpThread::AudioRtpThread(AudioSymmetricRtpSession *session) : running(true), rtpSession(session)
{}
AudioSymmetricRtpSession::AudioRtpThread::AudioRtpThread(AudioSymmetricRtpSession *session) : running_(true), rtpSession_(session)
{
assert(rtpSession_);
}
void AudioSymmetricRtpSession::AudioRtpThread::run()
{
......@@ -69,12 +70,12 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
DEBUG("AudioRtpThread: Entering Audio rtp thread main loop");
while (running) {
while (running_) {
// Send session
if (rtpSession->DtmfPending())
rtpSession->sendDtmfEvent();
if (rtpSession_->DtmfPending())
rtpSession_->sendDtmfEvent();
else
rtpSession->sendMicData();
rtpSession_->sendMicData();
Thread::sleep(TimerPort::getTimer());
......@@ -84,4 +85,20 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
DEBUG("AudioRtpThread: Leaving audio rtp thread loop");
}
void AudioSymmetricRtpSession::setSessionMedia(AudioCodec *audioCodec)
{
AudioRtpSession::setSessionMedia(audioCodec);
ca_->setRecordingSmplRate(getCodecSampleRate());
}
int AudioSymmetricRtpSession::startRtpThread(AudioCodec* audiocodec)
{
DEBUG("AudioSymmetricRtpSession: Starting main thread");
if (isStarted_)
return 0;
AudioRtpSession::startRtpThread(audiocodec);
return startSymmetricRtpThread();
}
}
......@@ -47,7 +47,6 @@ using std::ptrdiff_t;
#pragma GCC diagnostic ignored "-Weffc++"
#include <ccrtp/rtp.h>
#include <ccrtp/iqueue.h>
#include <cc++/numbers.h> // ost::Time
class SIPCall;
......@@ -60,7 +59,6 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
* @param sipcall The pointer on the SIP call
*/
AudioSymmetricRtpSession(SIPCall* sipcall);
~AudioSymmetricRtpSession();
virtual bool onRTPPacketRecv(ost::IncomingRTPPkt& pkt) {
......@@ -68,7 +66,6 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
}
int startSymmetricRtpThread() {
assert(rtpThread_);
return rtpThread_->start();
}
......@@ -78,19 +75,18 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
class AudioRtpThread : public ost::Thread, public ost::TimerPort {
public:
AudioRtpThread(AudioSymmetricRtpSession *session);
~AudioRtpThread(){}
virtual void run();
bool running;
bool running_;
private:
NON_COPYABLE(AudioRtpThread);
AudioSymmetricRtpSession *rtpSession;
AudioSymmetricRtpSession *rtpSession_;
};
SpeexEchoCancel echoCanceller;
void setSessionMedia(AudioCodec *codec);
int startRtpThread(AudioCodec* audiocodec);
private:
AudioRtpThread *rtpThread_;
};
......
......@@ -50,7 +50,7 @@
namespace sfl {
AudioZrtpSession::AudioZrtpSession(SIPCall * sipcall, const std::string& zidFilename) :
AudioRtpSession(sipcall, Zrtp, this, this),
AudioRtpSession(sipcall, this, this),
ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue>(ost::InetHostAddress(sipcall->getLocalIp().c_str()),
sipcall->getLocalAudioPort(),
0,
......@@ -117,6 +117,24 @@ void AudioZrtpSession::initializeZid()
return;
}
void AudioZrtpSession::sendMicData()
{
int compSize = processDataEncode();
// if no data return
if (compSize == 0)
return;
// Increment timestamp for outgoing packet
timestamp_ += timestampIncrement_;
// this step is only needed for ZRTP
queue_->putData(timestamp_, getMicDataEncoded(), compSize);
// putData puts the data on RTP queue, sendImmediate bypasses this queue
queue_->sendImmediate(timestamp_, getMicDataEncoded(), compSize);
}
void AudioZrtpSession::run()
{
// Set recording sampling rate
......@@ -165,4 +183,17 @@ void AudioZrtpSession::run()
DEBUG("AudioZrtpSession: Left main loop for call %s", ca_->getCallId().c_str());
}
void AudioZrtpSession::incrementTimestampForDTMF()
{
timestamp_ += 160;
}
void AudioZrtpSession::setSessionMedia(AudioCodec *audioCodec)
{
AudioRtpSession::setSessionMedia(audioCodec);
}
}
......@@ -43,6 +43,7 @@ using std::ptrdiff_t;
#include <cc++/numbers.h> // OST::Time