Commit 9e38ee2d authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Merge branch 'master' of...

Merge branch 'master' of git+ssh://repos-sflphone-git@git.sflphone.org/var/repos/sflphone/git/sflphone

Conflicts:
	sflphone-common/src/managerimpl.cpp
parents 073e7c24 bb1a13a0
......@@ -249,7 +249,7 @@ namespace sfl {
template <typename D>
AudioRtpSession<D>::~AudioRtpSession()
{
_debug ("Rtp: Delete AudioRtpSession instance");
_debug ("RTP: Delete AudioRtpSession instance");
try {
terminate();
......@@ -273,11 +273,9 @@ namespace sfl {
void AudioRtpSession<D>::initBuffers()
{
// Set sampling rate, main buffer choose the highest one
// _audiolayer->getMainBuffer()->setInternalSamplingRate(_codecSampleRate);
_manager->getAudioDriver()->getMainBuffer()->setInternalSamplingRate(_codecSampleRate);
// may be different than one already setted
// converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate();
_converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate();
// initialize SampleRate converter using AudioLayer's sampling rate
......@@ -311,28 +309,33 @@ namespace sfl {
{
assert(_ca);
_debug("RTP: Get audio codec for call %s", _ca->getCallId().c_str());
AudioCodecType pl = (AudioCodecType)_ca->getLocalSDP()->get_session_media()->getPayload();
_audiocodec = _manager->getCodecDescriptorMap().instantiateCodec(pl);
if (_audiocodec == NULL) {
_debug ("No audiocodec, can't init RTP media");
if (!_audiocodec) {
_error ("RTP: Error: No audiocodec, can't init RTP media");
throw AudioRtpSessionException();
}
_debug ("Init audio RTP session: codec payload %i", _audiocodec->getPayload());
_debug ("RTP: Init codec payload %i", _audiocodec->getPayload());
_codecSampleRate = _audiocodec->getClockRate();
_codecFrameSize = _audiocodec->getFrameSize();
_debug("RTP: Codec sampling rate: %d", _codecSampleRate);
_debug("RTP: Codec frame size: %d", _codecFrameSize);
//TODO: figure out why this is necessary.
if (_audiocodec->getPayload() == 9) {
_debug ("Setting payload format to G722");
_debug ("RTP: Setting payload format to G722");
static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate()));
} else if (_audiocodec->hasDynamicPayload()) {
_debug ("Setting a dynamic payload format");
_debug ("RTP: Setting a dynamic payload format");
static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate()));
} else if (!_audiocodec->hasDynamicPayload() && _audiocodec->getPayload() != 9) {
_debug ("Setting a static payload format");
_debug ("RTP: Setting a static payload format");
static_cast<D*>(this)->setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) _audiocodec->getPayload()));
}
}
......@@ -341,7 +344,7 @@ namespace sfl {
void AudioRtpSession<D>::setDestinationIpAddress(void)
{
if (_ca == NULL) {
_warn ("Rtp: Sipcall is gone.");
_error ("RTP: Sipcall is gone.");
throw AudioRtpSessionException();
}
......@@ -351,7 +354,7 @@ namespace sfl {
_remote_ip = ost::InetHostAddress(_ca->getLocalSDP()->get_remote_ip().c_str());
if (!_remote_ip) {
_warn("Rtp: Target IP address (%s) is not correct!",
_warn("RTP: Target IP address (%s) is not correct!",
_ca->getLocalSDP()->get_remote_ip().data());
return;
}
......@@ -363,7 +366,7 @@ namespace sfl {
_ca->getLocalSDP()->get_remote_ip().data(), _remote_port);
if (! static_cast<D*>(this)->addDestination (_remote_ip, _remote_port)) {
_warn("Rtp: Can't add new destination to session!");
_warn("RTP: Can't add new destination to session!");
return;
}
}
......@@ -375,7 +378,7 @@ namespace sfl {
// This method remove the current destination entry
if(!static_cast<D*>(this)->forgetDestination(_remote_ip, _remote_port, _remote_port+1))
_warn("Rtp: Could not remove previous destination");
_warn("RTP: Could not remove previous destination");
// new destination is stored in call
// we just need to recall this method
......@@ -619,7 +622,7 @@ namespace sfl {
template <typename D>
int AudioRtpSession<D>::startRtpThread ()
{
_debug("Starting main thread");
_debug("RTP: Starting main thread");
return start(_mainloopSemaphore);
}
......@@ -630,48 +633,50 @@ namespace sfl {
setSessionTimeouts();
setSessionMedia();
initBuffers();
initBuffers();
// Timestamp must be initialized randomly
_timestamp = static_cast<D*>(this)->getCurrentTimestamp();
// Timestamp must be initialized randomly
_timestamp = static_cast<D*>(this)->getCurrentTimestamp();
int sessionWaiting;
int threadSleep = 0;
if (_codecSampleRate != 0)
{ threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; }
else
{ threadSleep = _layerFrameSize; }
if (_codecSampleRate != 0){
threadSleep = (_codecFrameSize * 1000) / _codecSampleRate;
}
else {
threadSleep = _layerFrameSize;
}
TimerPort::setTimer (threadSleep);
if (_audiolayer == NULL) {
_debug("For some unknown reason, audiolayer is null, just as \
we were about to start the audio stream");
_error("RTP: Error: Audiolayer is null, cannot start the audio stream");
throw AudioRtpSessionException();
}
_ca->setRecordingSmplRate(_audiocodec->getClockRate());
_ca->setRecordingSmplRate(_audiocodec->getClockRate());
// Start audio stream (if not started) AND flush all buffers (main and urgent)
_manager->getAudioDriver()->startStream();
// Start audio stream (if not started) AND flush all buffers (main and urgent)
_manager->getAudioDriver()->startStream();
static_cast<D*>(this)->startRunning();
_debug ("Entering RTP mainloop for callid %s",_ca->getCallId().c_str());
_debug ("RTP: Entering mainloop for call %s",_ca->getCallId().c_str());
while (!testCancel()) {
// ost::MutexLock lock(*(_manager->getAudioLayerMutex()));
// ost::MutexLock lock(*(_manager->getAudioLayerMutex()));
_manager->getAudioLayerMutex()->enter();
_manager->getAudioLayerMutex()->enter();
// converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate();
_manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate();
// converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate();
_converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate();
// Send session
sessionWaiting = static_cast<D*>(this)->isWaiting();
sessionWaiting = static_cast<D*>(this)->isWaiting();
// Send session
if(_eventQueue.size() > 0) {
sendDtmfEvent(_eventQueue.front());
}
......@@ -698,7 +703,7 @@ namespace sfl {
TimerPort::incTimer (threadSleep);
}
_debug ("Left RTP main loop for callid %s",_ca->getCallId().c_str());
_debug ("RTP: Left main loop for call%s", _ca->getCallId().c_str());
}
}
......
......@@ -49,7 +49,7 @@ CELT_LIB = libcodec_celt.so
libcodec_celt_so_SOURCES = celtcodec.cpp
libcodec_celt_so_CFLAGS = -fPIC -g -Wall
libcodec_celt_so_CXXFLAGS = -fPIC -g -Wall
libcodec_celt_so_LDFLAGS = --shared -lc -lcelt $(CELT_NIMP)
libcodec_celt_so_LDFLAGS = --shared -lc -lcelt0 $(CELT_NIMP)
INSTALL_CELT_RULE = install-libcodec_celt_so
endif
......
......@@ -26,27 +26,59 @@ class Celt : public AudioCodec
{
public:
Celt (int payload=0)
: AudioCodec (payload, "celt") {
_clockRate = 44100;
_frameSize = 512; // fixed frameSize, TODO: support variable size from 64 to 512
Celt (int payload=0) : AudioCodec (payload, "celt") {
_clockRate = 32000;
_frameSize = 320; // fixed frameSize, TODO: support variable size from 64 to 512
_channel = 1;
_bitrate = 0;
_bandwidth = 0;
initCelt();
}
Celt (const Celt&);
Celt& operator= (const Celt&);
void initCelt() {
printf ("init celt");
printf ("Celt: Init Celt codec");
int error = 0;
_mode = celt_mode_create (_clockRate, _frameSize, &error);
if(error != CELT_OK) {
switch(error) {
case CELT_BAD_ARG:
printf("Celt: Error: An (or more) invalid argument (e.g. out of range)\n");
break;
case CELT_INVALID_MODE:
printf("Celt: Error: The mode struct passed is invalid\n");
break;
case CELT_INTERNAL_ERROR:
printf("Celt: Error: An internal error was detected\n");
break;
case CELT_CORRUPTED_DATA:
printf("Celt: Error: The data passed (e.g. compressed data to decoder) is corrupted\n");
break;
case CELT_UNIMPLEMENTED:
printf("Celt: Error: Invalid/unsupported request numbe\n");
break;
case CELT_INVALID_STATE:
printf("Celt: Error: An encoder or decoder structure is invalid or already freed\n");
break;
case CELT_ALLOC_FAIL:
printf("Celt: Error: Memory allocation has failed\n");
break;
default:
printf("Celt: Error");
}
mode = celt_mode_create (_clockRate, _channel, _frameSize, NULL);
// celt_mode_info(mode, CELT_GET_LOOKAHEAD, &skip);
}
if (mode == NULL) {
printf ("failed to create a mode");
if (_mode == NULL) {
printf ("Celt: Error: Failed to create Celt mode");
}
// bytes_per_packet = 1024;
......@@ -58,11 +90,12 @@ class Celt : public AudioCodec
// celt_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size);
// celt_mode_info(mode, CELT_GET_NB_CHANNELS, &_channel);
enc = celt_encoder_create (mode);
_enc = celt_encoder_create (_mode, _channel, &error);
dec = celt_decoder_create (mode);
_dec = celt_decoder_create (_mode, _channel, &error);
celt_encoder_ctl (enc,CELT_SET_COMPLEXITY (10));
celt_encoder_ctl (_enc, CELT_SET_COMPLEXITY (10));
celt_decoder_ctl(_dec, CELT_SET_COMPLEXITY (10));
}
......@@ -72,32 +105,34 @@ class Celt : public AudioCodec
void terminateCelt() {
celt_encoder_destroy (enc);
celt_decoder_destroy (dec);
celt_encoder_destroy (_enc);
celt_decoder_destroy (_dec);
celt_mode_destroy(_mode);
}
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size) {
int err = 0;
err = celt_decode (dec, src, size, (celt_int16_t*) dst);
return _frameSize * sizeof (celt_int16_t);
err = celt_decode (_dec, src, size, (celt_int16*) dst);
return _frameSize * sizeof (celt_int16);
}
virtual int codecEncode (unsigned char *dst, short *src, unsigned int size) {
int len = 0;
len = celt_encode (enc, (celt_int16_t *) src, (celt_int16_t *) src, dst, 512);
len = celt_encode (_enc, (celt_int16*) src, (celt_int16 *) src, dst, 512);
// returns the number of bytes writen
return len;
}
private:
CELTMode *mode;
CELTMode *_mode;
CELTEncoder *enc;
CELTDecoder *dec;
CELTEncoder *_enc;
CELTDecoder *_dec;
celt_int32_t _celt_frame_size;
celt_int32_t skip;
celt_int32 _celt_frame_size;
celt_int32 skip;
};
......
......@@ -39,7 +39,7 @@ class Speex : public AudioCodec
_clockRate = 8000;
_frameSize = 160; // samples, 20 ms at 8kHz
_channel = 1;
_bitrate = 0;
_bitrate = 24;
_bandwidth = 0;
initSpeex();
}
......
......@@ -39,7 +39,7 @@ class Speex : public AudioCodec
_clockRate = 16000;
_frameSize = 320; // 20 ms at 16 kHz
_channel = 1;
_bitrate = 0;
_bitrate = 42;
_bandwidth = 0;
initSpeex();
}
......
......@@ -77,14 +77,14 @@ CallManager::placeCallFirstAccount (const std::string& callID,
void
CallManager::refuse (const std::string& callID)
{
_debug ("CallManager::refuse received");
_debug ("CallManager: refuse received");
Manager::instance().refuseCall (callID);
}
void
CallManager::accept (const std::string& callID)
{
_debug ("CallManager::accept received");
_debug ("CallManager: accept received");
Manager::instance().answerCall (callID);
}
......
......@@ -376,7 +376,9 @@ bool ManagerImpl::answerCall (const CallID& call_id) {
//THREAD=Main
bool ManagerImpl::hangupCall (const CallID& call_id) {
_debug ("ManagerImpl::hangupCall(%s)", call_id.c_str());
_info("Manager: Hangup call %s", call_id.c_str());
PulseLayer *pulselayer;
AccountID account_id;
bool returnValue = true;
......@@ -387,7 +389,7 @@ bool ManagerImpl::hangupCall (const CallID& call_id) {
stopTone();
/* Broadcast a signal over DBus */
_debug (" hangupCall: Send DBUS call state change (HUNGUP) for id %s", call_id.c_str());
_debug ("Manager: Send DBUS call state change (HUNGUP) for id %s", call_id.c_str());
if (_dbus)
_dbus->getCallManager()->callStateChanged(call_id, "HUNGUP");
......@@ -419,7 +421,7 @@ bool ManagerImpl::hangupCall (const CallID& call_id) {
if (account_id == AccountNULL) {
_debug ("! Manager Hangup Call: Call doesn't exists");
_error ("Manager: Error: account id is NULL in hangup");
returnValue = false;
} else {
......@@ -434,7 +436,7 @@ bool ManagerImpl::hangupCall (const CallID& call_id) {
// stop streams
if (audiolayer && (nbCalls <= 0)) {
_debug (" hangupCall: stop audio stream, ther is only %i call(s) remaining", nbCalls);
_debug ("Manager: stop audio stream, ther is only %i call(s) remaining", nbCalls);
audiolayer->stopStream();
}
......@@ -446,7 +448,8 @@ bool ManagerImpl::hangupCall (const CallID& call_id) {
}
bool ManagerImpl::hangupConference (const ConfID& id) {
_debug ("ManagerImpl::hangupConference()");
_debug ("Manager: Hangup conference %s", id.c_str());
Conference *conf;
ConferenceMap::iterator iter_conf = _conferencemap.find(id);
......@@ -463,7 +466,7 @@ bool ManagerImpl::hangupConference (const ConfID& id) {
ParticipantSet::iterator iter_participant = participants.begin();
while (iter_participant != participants.end()) {
_debug ("ManagerImpl::hangupConference participant %s", (*iter_participant).c_str());
_debug ("Manager: Hangup onference participant %s", (*iter_participant).c_str());
hangupCall(*iter_participant);
......@@ -483,6 +486,8 @@ bool ManagerImpl::cancelCall (const CallID& id) {
AccountID accountid;
bool returnValue;
_debug("Manager: Cancel call");
stopTone();
/* Direct IP to IP call */
......@@ -518,13 +523,12 @@ bool ManagerImpl::onHoldCall (const CallID& call_id) {
AccountID account_id;
bool returnValue;
_debug ("ManagerImpl::onHoldCall(%s)", call_id.c_str());
_debug ("Manager: Put call %s on hold", call_id.c_str());
stopTone();
CallID current_call_id = getCurrentCallId();
_debug (" onHoldCall: try to put call %s on hold", call_id.c_str());
/* Direct IP to IP call */
......@@ -537,7 +541,7 @@ bool ManagerImpl::onHoldCall (const CallID& call_id) {
account_id = getAccountFromCall(call_id);
if (account_id == AccountNULL) {
_debug (" onHoldCall: Account ID %s or callid %s doesn't exists", account_id.c_str(), call_id.c_str());
_debug ("Manager: Account ID %s or callid %s doesn't exists in call onHold", account_id.c_str(), call_id.c_str());
return false;
}
......@@ -568,7 +572,7 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) {
is_rec = false;
_debug ("ManagerImpl::offHoldCall(%s)", call_id.c_str());
_debug ("Manager: Put call %s off hold", call_id.c_str());
stopTone();
......@@ -580,11 +584,9 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) {
// if this is not a conferenceand this and is not a conference participant
if (!isConference(current_call_id) && !participToConference(
current_call_id)) {
_debug (" offHoldCall: put current call (%s) on hold", current_call_id.c_str());
onHoldCall(current_call_id);
} else if (isConference(current_call_id) && !participToConference(
call_id)) {
_debug (" offHoldCall Put current conference (%s) on hold", current_call_id.c_str());
detachParticipant(default_id, current_call_id);
}
}
......@@ -603,11 +605,11 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) {
account_id = getAccountFromCall(call_id);
if (account_id == AccountNULL) {
_debug ("Manager OffHold Call: Call doesn't exists");
_warn ("Manager: Error: Call doesn't exists in off hold");
return false;
}
_debug ("Setting OFFHOLD, Account %s, callid %s", account_id.c_str(), call_id.c_str());
_debug ("Manager: Setting offhold, Account %s, callid %s", account_id.c_str(), call_id.c_str());
is_rec = getAccountLink(account_id)->getCall(call_id)->isRecording();
returnValue = getAccountLink(account_id)->offhold(call_id);
......@@ -636,12 +638,6 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) {
_audiodriver->flushMain();
}
// codecName = getCurrentCodecName (call_id);
// _debug("ManagerImpl::hangupCall(): broadcast codec name %s ",codecName.c_str());
// if (_dbus) _dbus->getCallManager()->currentSelectedCodec (call_id,codecName.c_str());
return returnValue;
}
......@@ -650,39 +646,18 @@ bool ManagerImpl::transferCall (const CallID& call_id, const std::string& to) {
AccountID accountid;
bool returnValue;
_info("Manager: Transfer Call\n");
stopTone();
_info("Manager: Transfer call %s\n", call_id.c_str());
CallID current_call_id = getCurrentCallId();
if (participToConference(call_id)) {
_info("Manager: Particip to a conference\n");
Conference *conf = getConferenceFromCallID(call_id);
if (conf != NULL) {
// remove this participant
removeParticipant(call_id);
processRemainingParticipant(current_call_id, conf);
}
} else {
// we are not participating to a conference, current call switched to ""
if (!isConference(current_call_id))
switchCall("");
}
/* Direct IP to IP call */
// Direct IP to IP call
if (getConfigFromCall(call_id) == Call::IPtoIP) {
returnValue
= SIPVoIPLink::instance(AccountNULL)-> transfer(call_id, to);
returnValue = SIPVoIPLink::instance(AccountNULL)-> transfer(call_id, to);
}
/* Classic call, attached to an account */
// Classic call, attached to an account
else {
accountid = getAccountFromCall(call_id);
accountid = getAccountFromCall(call_id);
if (accountid == AccountNULL) {
_warn ("Manager: Call doesn't exists");
......@@ -691,9 +666,9 @@ bool ManagerImpl::transferCall (const CallID& call_id, const std::string& to) {
returnValue = getAccountLink(accountid)->transfer(call_id, to);
removeCallAccount(call_id);
}
// remove waiting call in case we make transfer without even answer
removeWaitingCall(call_id);
return returnValue;
......@@ -721,6 +696,8 @@ bool ManagerImpl::refuseCall (const CallID& id) {
AccountID accountid;
bool returnValue;
_debug("Manager: Refuse call %s", id.c_str());
CallID current_call_id = getCurrentCallId();
stopTone();
......@@ -730,12 +707,14 @@ bool ManagerImpl::refuseCall (const CallID& id) {
// AudioLayer* audiolayer = getAudioDriver();
if (nbCalls <= 1) {
_debug (" refuseCall: stop audio stream, ther is only %i call(s) remaining", nbCalls);
_debug (" refuseCall: stop audio stream, there is only %i call(s) remaining", nbCalls);
AudioLayer* audiolayer = getAudioDriver();
audiolayer->stopStream();
}
_debug("OK");
/* Direct IP to IP call */
if (getConfigFromCall(id) == Call::IPtoIP) {
......@@ -747,7 +726,7 @@ bool ManagerImpl::refuseCall (const CallID& id) {
accountid = getAccountFromCall(id);
if (accountid == AccountNULL) {
_debug ("! Manager refuseCall: Call doesn't exists");
_warn ("Manager: Call doesn't exists");
return false;
}
......@@ -755,6 +734,7 @@ bool ManagerImpl::refuseCall (const CallID& id) {
removeCallAccount(id);
}
_debug("OK");
// if the call was outgoing or established, we didn't refuse it
// so the method did nothing
......@@ -763,9 +743,6 @@ bool ManagerImpl::refuseCall (const CallID& id) {
if (_dbus)
_dbus->getCallManager()->callStateChanged(id, "HUNGUP");
// if(current_call_id.compare("") != 0)
// switchCall ("");
}
return returnValue;
......@@ -1545,18 +1522,24 @@ bool ManagerImpl::incomingCallWaiting () {
}
void ManagerImpl::addWaitingCall (const CallID& id) {
ost::MutexLock m(_waitingCallMutex);
_waitingCall.insert(id);
_nbIncomingWaitingCall++;
_info("Manager: Add waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall);
}
void ManagerImpl::removeWaitingCall (const CallID& id) {
ost::MutexLock m(_waitingCallMutex);
// should return more than 1 if it erase a call