Skip to content
Snippets Groups Projects
Commit e54472ab authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#4367] Fix zrtp session

parent 61efb9f2
No related branches found
No related tags found
No related merge requests found
...@@ -50,6 +50,13 @@ namespace sfl ...@@ -50,6 +50,13 @@ namespace sfl
static const int schedulingTimeout = 10000; static const int schedulingTimeout = 10000;
static const int expireTimeout = 100000; static const int expireTimeout = 100000;
// G.722 VoIP is typically carried in RTP payload type 9.[2] Note that IANA records the clock rate for type 9 G.722 as 8 kHz
// (instead of 16 kHz), RFC3551[3] clarifies that this is due to a historical error and is retained in order to maintain backward
// compatibility. Consequently correct implementations represent the value 8,000 where required but encode and decode audio at 16 kHz.
static const int g722PayloadType = 9;
static const int g722RtpClockRate = 8000;
static const int g722RtpTimeincrement = 160;
class AudioRtpSessionException: public std::exception class AudioRtpSessionException: public std::exception
{ {
virtual const char* what() const throw() { virtual const char* what() const throw() {
......
...@@ -72,7 +72,7 @@ AudioRtpSession::AudioRtpSession (ManagerImpl * manager, SIPCall * sipcall) : ...@@ -72,7 +72,7 @@ AudioRtpSession::AudioRtpSession (ManagerImpl * manager, SIPCall * sipcall) :
// static_cast<ost::DualRTPUDPIPv4Channel>(dso)->sendSocket->setTypeOfService(ost::Socket::tosLowDelay); // static_cast<ost::DualRTPUDPIPv4Channel>(dso)->sendSocket->setTypeOfService(ost::Socket::tosLowDelay);
// static_cast<ost::DualRTPChannel<ost::DualRTPUDPIPv4Channel> >(dso)->sendSocket->setTypeOfService(ost::Socket::tosLowDelay); // static_cast<ost::DualRTPChannel<ost::DualRTPUDPIPv4Channel> >(dso)->sendSocket->setTypeOfService(ost::Socket::tosLowDelay);
// setTypeOfService(tosEnhanced); setTypeOfService(tosEnhanced);
} }
AudioRtpSession::~AudioRtpSession() AudioRtpSession::~AudioRtpSession()
...@@ -133,7 +133,7 @@ void AudioRtpSession::setSessionMedia (AudioCodec* audioCodec) ...@@ -133,7 +133,7 @@ void AudioRtpSession::setSessionMedia (AudioCodec* audioCodec)
} else if (dynamic) { } else if (dynamic) {
_debug ("AudioRtpSession: Setting dynamic payload format"); _debug ("AudioRtpSession: Setting dynamic payload format");
setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) payloadType, smplRate)); setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) payloadType, smplRate));
} else if (dynamic && payloadType != 9) { } else if (dynamic && payloadType != g722PayloadType) {
_debug ("AudioRtpSession: Setting static payload format"); _debug ("AudioRtpSession: Setting static payload format");
setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) payloadType)); setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) payloadType));
} }
...@@ -229,8 +229,6 @@ void AudioRtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf) ...@@ -229,8 +229,6 @@ void AudioRtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf)
bool AudioRtpSession::onRTPPacketRecv (ost::IncomingRTPPkt&) bool AudioRtpSession::onRTPPacketRecv (ost::IncomingRTPPkt&)
{ {
// _debug ("AudioRtpSession: onRTPPacketRecv");
receiveSpeakerData (); receiveSpeakerData ();
return true; return true;
...@@ -257,7 +255,6 @@ void AudioRtpSession::sendMicData() ...@@ -257,7 +255,6 @@ void AudioRtpSession::sendMicData()
// putData put the data on RTP queue, sendImmediate bypass this queue // putData put the data on RTP queue, sendImmediate bypass this queue
putData (_timestamp, getMicDataEncoded(), compSize); putData (_timestamp, getMicDataEncoded(), compSize);
// sendData()
} }
...@@ -322,6 +319,7 @@ void AudioRtpSession::run () ...@@ -322,6 +319,7 @@ void AudioRtpSession::run ()
// Timestamp must be initialized randomly, already done when instantiating outgoing queue // Timestamp must be initialized randomly, already done when instantiating outgoing queue
_timestamp = getCurrentTimestamp(); _timestamp = getCurrentTimestamp();
/**
int threadSleep = 0; int threadSleep = 0;
if (getCodecSampleRate() != 0) { if (getCodecSampleRate() != 0) {
...@@ -332,6 +330,7 @@ void AudioRtpSession::run () ...@@ -332,6 +330,7 @@ void AudioRtpSession::run ()
} }
TimerPort::setTimer (threadSleep); TimerPort::setTimer (threadSleep);
*/
// Set recording sampling rate // Set recording sampling rate
_ca->setRecordingSmplRate (getCodecSampleRate()); _ca->setRecordingSmplRate (getCodecSampleRate());
...@@ -347,8 +346,6 @@ void AudioRtpSession::run () ...@@ -347,8 +346,6 @@ void AudioRtpSession::run ()
timeout = getSchedulingTimeout(); timeout = getSchedulingTimeout();
} }
// timeout = ;
_manager->getAudioLayerMutex()->enter(); _manager->getAudioLayerMutex()->enter();
// Send session // Send session
...@@ -389,7 +386,6 @@ void AudioRtpSession::run () ...@@ -389,7 +386,6 @@ void AudioRtpSession::run ()
timeout = 0; timeout = 0;
} }
// receiveSpeakerData();
} }
_debug ("AudioRtpSession: Left main loop for call %s", _ca->getCallId().c_str()); _debug ("AudioRtpSession: Left main loop for call %s", _ca->getCallId().c_str());
......
...@@ -57,13 +57,6 @@ ...@@ -57,13 +57,6 @@
namespace sfl namespace sfl
{ {
// G.722 VoIP is typically carried in RTP payload type 9.[2] Note that IANA records the clock rate for type 9 G.722 as 8 kHz
// (instead of 16 kHz), RFC3551[3] clarifies that this is due to a historical error and is retained in order to maintain backward
// compatibility. Consequently correct implementations represent the value 8,000 where required but encode and decode audio at 16 kHz.
static const int g722PayloadType = 9;
static const int g722RtpClockRate = 8000;
static const int g722RtpTimeincrement = 160;
// class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public AudioRtpRecordHandler, public ost::TRTPSessionBase<ost::DualRTPUDPIPv4Channel,ost::DualRTPUDPIPv4Channel,ost::AVPQueue> // class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public AudioRtpRecordHandler, public ost::TRTPSessionBase<ost::DualRTPUDPIPv4Channel,ost::DualRTPUDPIPv4Channel,ost::AVPQueue>
class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public AudioRtpRecordHandler, public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::AVPQueue> class AudioRtpSession : protected ost::Thread, public ost::TimerPort, public AudioRtpRecordHandler, public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::AVPQueue>
{ {
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "sip/sipcall.h" #include "sip/sipcall.h"
#include "sip/sdp.h" #include "sip/sdp.h"
#include "audio/audiolayer.h" #include "audio/audiolayer.h"
#include "manager.h"
#include <libzrtpcpp/ZrtpQueue.h> #include <libzrtpcpp/ZrtpQueue.h>
#include <libzrtpcpp/ZrtpUserCallback.h> #include <libzrtpcpp/ZrtpUserCallback.h>
...@@ -64,7 +65,9 @@ AudioZrtpSession::AudioZrtpSession (ManagerImpl * manager, SIPCall * sipcall, co ...@@ -64,7 +65,9 @@ AudioZrtpSession::AudioZrtpSession (ManagerImpl * manager, SIPCall * sipcall, co
assert (_ca); assert (_ca);
_info ("AudioZrtpSession: Local audio port %i will be used", _ca->getLocalAudioPort()); _info ("AudioZrtpSession: Setting new RTP session with destination %s:%d", _ca->getLocalIp().c_str(), _ca->getLocalAudioPort());
setTypeOfService(tosEnhanced);
} }
AudioZrtpSession::~AudioZrtpSession() AudioZrtpSession::~AudioZrtpSession()
...@@ -134,12 +137,16 @@ void AudioZrtpSession::initializeZid (void) ...@@ -134,12 +137,16 @@ void AudioZrtpSession::initializeZid (void)
void AudioZrtpSession::setSessionTimeouts (void) void AudioZrtpSession::setSessionTimeouts (void)
{ {
_debug("AudioZrtpSession: Set session scheduling timeout (%d) and expireTimeout (%d)", sfl::schedulingTimeout, sfl::expireTimeout);
setSchedulingTimeout (sfl::schedulingTimeout); setSchedulingTimeout (sfl::schedulingTimeout);
setExpireTimeout (sfl::expireTimeout); setExpireTimeout (sfl::expireTimeout);
} }
void AudioZrtpSession::setSessionMedia (AudioCodec* audioCodec) void AudioZrtpSession::setSessionMedia (AudioCodec* audioCodec)
{ {
_debug("AudioRtpSession: Set session media");
// set internal codec info for this session // set internal codec info for this session
setRtpMedia(audioCodec); setRtpMedia(audioCodec);
...@@ -150,24 +157,25 @@ void AudioZrtpSession::setSessionMedia (AudioCodec* audioCodec) ...@@ -150,24 +157,25 @@ void AudioZrtpSession::setSessionMedia (AudioCodec* audioCodec)
bool dynamic = getHasDynamicPayload(); bool dynamic = getHasDynamicPayload();
// G722 requires timestamp to be incremented at 8 kHz // G722 requires timestamp to be incremented at 8 kHz
if (payloadType == 9) if (payloadType == g722PayloadType)
_timestampIncrement = 160; _timestampIncrement = g722RtpTimeincrement;
else else
_timestampIncrement = frameSize; _timestampIncrement = frameSize;
_debug ("AudioRtpSession: Codec sampling rate: %d", smplRate); _debug ("AudioZrtpSession: Codec payload: %d", payloadType);
_debug ("AudioRtpSession: Codec frame size: %d", frameSize); _debug ("AudioZrtpSession: Codec sampling rate: %d", smplRate);
_debug ("AudioRtpSession: RTP timestamp increment: %d", _timestampIncrement); _debug ("AudioZrtpSession: Codec frame size: %d", frameSize);
_debug ("AudioZrtpSession: RTP timestamp increment: %d", _timestampIncrement);
// Even if specified as a 16 kHz codec, G722 requires rtp sending rate to be 8 kHz // Even if specified as a 16 kHz codec, G722 requires rtp sending rate to be 8 kHz
if (payloadType == 9) { if (payloadType == g722PayloadType) {
_debug ("AudioRtpSession: Setting G722 payload format"); _debug ("AudioZrtpSession: Setting G722 payload format");
setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) payloadType, smplRate)); setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) payloadType, g722RtpClockRate));
} else if (dynamic) { } else if (dynamic) {
_debug ("AudioRtpSession: Setting dynamic payload format"); _debug ("AudioZrtpSession: Setting dynamic payload format");
setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) payloadType, smplRate)); setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) payloadType, smplRate));
} else if (dynamic && payloadType != 9) { } else if (dynamic && payloadType != g722PayloadType) {
_debug ("AudioRtpSession: Setting static payload format"); _debug ("AudioZrtpSession: Setting static payload format");
setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) payloadType)); setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) payloadType));
} }
...@@ -175,18 +183,18 @@ void AudioZrtpSession::setSessionMedia (AudioCodec* audioCodec) ...@@ -175,18 +183,18 @@ void AudioZrtpSession::setSessionMedia (AudioCodec* audioCodec)
void AudioZrtpSession::setDestinationIpAddress (void) void AudioZrtpSession::setDestinationIpAddress (void)
{ {
_info ("AudioZrtpSession: Setting IP address for the RTP session");
if (_ca == NULL) { if (_ca == NULL) {
_error ("AudioRtpSession: Sipcall is gone."); _error ("AudioZrtpSession: Sipcall is gone.");
throw AudioRtpSessionException(); throw AudioRtpSessionException();
} }
_info ("AudioRtpSession: Setting IP address for the RTP session");
// Store remote ip in case we would need to forget current destination // Store remote ip in case we would need to forget current destination
_remote_ip = ost::InetHostAddress (_ca->getLocalSDP()->get_remote_ip().c_str()); _remote_ip = ost::InetHostAddress (_ca->getLocalSDP()->get_remote_ip().c_str());
if (!_remote_ip) { if (!_remote_ip) {
_warn ("AudioRtpSession: Target IP address (%s) is not correct!", _warn ("AudioZrtpSession: Target IP address (%s) is not correct!",
_ca->getLocalSDP()->get_remote_ip().data()); _ca->getLocalSDP()->get_remote_ip().data());
return; return;
} }
...@@ -194,22 +202,24 @@ void AudioZrtpSession::setDestinationIpAddress (void) ...@@ -194,22 +202,24 @@ void AudioZrtpSession::setDestinationIpAddress (void)
// Store remote port in case we would need to forget current destination // Store remote port in case we would need to forget current destination
_remote_port = (unsigned short) _ca->getLocalSDP()->get_remote_audio_port(); _remote_port = (unsigned short) _ca->getLocalSDP()->get_remote_audio_port();
_info ("AudioRtpSession: New remote address for session: %s:%d", _info ("AudioZrtpSession: New remote address for session: %s:%d",
_ca->getLocalSDP()->get_remote_ip().data(), _remote_port); _ca->getLocalSDP()->get_remote_ip().data(), _remote_port);
if (!addDestination (_remote_ip, _remote_port)) { if (!addDestination (_remote_ip, _remote_port)) {
_warn ("AudioRtpSession: Can't add new destination to session!"); _warn ("AudioZrtpSession: Can't add new destination to session!");
return; return;
} }
} }
void AudioZrtpSession::updateDestinationIpAddress (void) void AudioZrtpSession::updateDestinationIpAddress (void)
{ {
_debug("AudioZrtpSession: Update destination ip address");
// Destination address are stored in a list in ccrtp // Destination address are stored in a list in ccrtp
// This method remove the current destination entry // This method remove the current destination entry
if (!forgetDestination (_remote_ip, _remote_port, _remote_port+1)) if (!forgetDestination (_remote_ip, _remote_port, _remote_port+1))
_warn ("AudioRtpSession: Could not remove previous destination"); _warn ("AudioZrtpSession: Could not remove previous destination");
// new destination is stored in call // new destination is stored in call
// we just need to recall this method // we just need to recall this method
...@@ -218,7 +228,7 @@ void AudioZrtpSession::updateDestinationIpAddress (void) ...@@ -218,7 +228,7 @@ void AudioZrtpSession::updateDestinationIpAddress (void)
void AudioZrtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf) void AudioZrtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf)
{ {
_debug ("AudioRtpSession: Send Dtmf %d", getEventQueueSize()); _debug ("AudioZrtpSession: Send Dtmf %d", getEventQueueSize());
_timestamp += 160; _timestamp += 160;
...@@ -258,9 +268,9 @@ void AudioZrtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf) ...@@ -258,9 +268,9 @@ void AudioZrtpSession::sendDtmfEvent (sfl::DtmfEvent *dtmf)
} }
} }
bool onRTPPacketRecv (ost::IncomingRTPPkt&) bool AudioZrtpSession::onRTPPacketRecv (ost::IncomingRTPPkt&)
{ {
_debug ("AudioRtpSession: onRTPPacketRecv"); receiveSpeakerData();
return true; return true;
} }
...@@ -268,10 +278,23 @@ bool onRTPPacketRecv (ost::IncomingRTPPkt&) ...@@ -268,10 +278,23 @@ bool onRTPPacketRecv (ost::IncomingRTPPkt&)
void AudioZrtpSession::sendMicData() void AudioZrtpSession::sendMicData()
{ {
int compSize = processDataEncode();
// if no data return
if(!compSize)
return;
// Increment timestamp for outgoing packet // Increment timestamp for outgoing packet
_timestamp += _timestampIncrement; _timestamp += _timestampIncrement;
int compSize = processDataEncode(); // Reset timestamp to make sure the timing information are up to date
if (_timestampCount > RTP_TIMESTAMP_RESET_FREQ) {
_timestamp = getCurrentTimestamp();
_timestampCount = 0;
}
// Increment timestamp for outgoing packet
_timestamp += _timestampIncrement;
// putData put the data on RTP queue, sendImmediate bypass this queue // putData put the data on RTP queue, sendImmediate bypass this queue
putData (_timestamp, getMicDataEncoded(), compSize); putData (_timestamp, getMicDataEncoded(), compSize);
...@@ -293,15 +316,9 @@ void AudioZrtpSession::receiveSpeakerData () ...@@ -293,15 +316,9 @@ void AudioZrtpSession::receiveSpeakerData ()
unsigned char* spkrDataIn = NULL; unsigned char* spkrDataIn = NULL;
unsigned int size = 0; unsigned int size = 0;
if (adu) {
spkrDataIn = (unsigned char*) adu->getData(); // data in char spkrDataIn = (unsigned char*) adu->getData(); // data in char
size = adu->getSize(); // size in char size = adu->getSize(); // size in char
} else {
_debug ("AudioRtpSession: No RTP packet available");
}
// DTMF over RTP, size must be over 4 in order to process it as voice data // DTMF over RTP, size must be over 4 in order to process it as voice data
if (size > 4) { if (size > 4) {
processDataDecode (spkrDataIn, size); processDataDecode (spkrDataIn, size);
...@@ -310,14 +327,32 @@ void AudioZrtpSession::receiveSpeakerData () ...@@ -310,14 +327,32 @@ void AudioZrtpSession::receiveSpeakerData ()
delete adu; delete adu;
} }
void AudioZrtpSession::notifyIncomingCall()
{
// Notify (with a beep) an incoming call when there is already a call
if (Manager::instance().incomingCallWaiting() > 0) {
_countNotificationTime += _time->getSecond();
int countTimeModulo = _countNotificationTime % 5000;
if ( (countTimeModulo - _countNotificationTime) < 0) {
Manager::instance().notificationIncomingCall();
}
_countNotificationTime = countTimeModulo;
}
}
int AudioZrtpSession::startRtpThread (AudioCodec* audiocodec) int AudioZrtpSession::startRtpThread (AudioCodec* audiocodec)
{ {
_debug ("RTP: Starting main thread"); _debug ("AudioZrtpSession: Starting main thread");
setSessionTimeouts(); setSessionTimeouts();
setSessionMedia (audiocodec); setSessionMedia (audiocodec);
initBuffers(); initBuffers();
return start (_mainloopSemaphore); initNoiseSuppress();
enableStack();
int ret = start(_mainloopSemaphore);
return ret;
} }
void AudioZrtpSession::run () void AudioZrtpSession::run ()
...@@ -335,8 +370,6 @@ void AudioZrtpSession::run () ...@@ -335,8 +370,6 @@ void AudioZrtpSession::run ()
threadSleep = getAudioLayerFrameSize(); threadSleep = getAudioLayerFrameSize();
} }
initNoiseSuppress();
TimerPort::setTimer (threadSleep); TimerPort::setTimer (threadSleep);
// Set recording sampling rate // Set recording sampling rate
...@@ -344,9 +377,8 @@ void AudioZrtpSession::run () ...@@ -344,9 +377,8 @@ void AudioZrtpSession::run ()
// Start audio stream (if not started) AND flush all buffers (main and urgent) // Start audio stream (if not started) AND flush all buffers (main and urgent)
_manager->getAudioDriver()->startStream(); _manager->getAudioDriver()->startStream();
startRunning();
_debug ("AudioRtpSession: Entering mainloop for call %s",_ca->getCallId().c_str()); _debug ("AudioZrtpSession: Entering mainloop for call %s",_ca->getCallId().c_str());
while (!testCancel()) { while (!testCancel()) {
...@@ -384,7 +416,7 @@ void AudioZrtpSession::run () ...@@ -384,7 +416,7 @@ void AudioZrtpSession::run ()
TimerPort::incTimer (threadSleep); TimerPort::incTimer (threadSleep);
} }
_debug ("AudioRtpSession: Left main loop for call %s", _ca->getCallId().c_str()); _debug ("AudioZrtpSession: Left main loop for call %s", _ca->getCallId().c_str());
} }
} }
...@@ -57,6 +57,8 @@ class AudioZrtpSession : public ost::TimerPort, public ost::SymmetricZRTPSession ...@@ -57,6 +57,8 @@ class AudioZrtpSession : public ost::TimerPort, public ost::SymmetricZRTPSession
// Thread associated method // Thread associated method
virtual void run (); virtual void run ();
virtual bool onRTPPacketRecv (ost::IncomingRTPPkt&);
int startRtpThread (AudioCodec*); int startRtpThread (AudioCodec*);
/** /**
...@@ -92,6 +94,8 @@ class AudioZrtpSession : public ost::TimerPort, public ost::SymmetricZRTPSession ...@@ -92,6 +94,8 @@ class AudioZrtpSession : public ost::TimerPort, public ost::SymmetricZRTPSession
void setDestinationIpAddress (void); void setDestinationIpAddress (void);
void notifyIncomingCall();
/** /**
* Send encoded data to peer * Send encoded data to peer
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment