Commit 39764571 authored by Rafaël Carré's avatar Rafaël Carré

* #6991 : fix IAX problems

parent 8ec5699e
......@@ -42,7 +42,8 @@ doc/doxygen/gtk-gui-doc
doc/*.html
# Ignore built stuff
/src/.libs
.libs
.deps
# PJSIP files
*.depend
......
......@@ -523,7 +523,7 @@ namespace
void AlsaLayer::capture(void)
{
unsigned int mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
int toGetSamples = snd_pcm_avail_update (captureHandle_);
......@@ -550,11 +550,11 @@ void AlsaLayer::capture(void)
SFLDataFormat* rsmpl_out = (SFLDataFormat*) malloc (outBytes);
converter_->resample ( (SFLDataFormat*) in, rsmpl_out, mainBufferSampleRate, audioSampleRate_, toGetSamples);
dcblocker_.process(rsmpl_out, rsmpl_out, outSamples);
getMainBuffer()->putData (rsmpl_out, outBytes);
Manager::instance().getMainBuffer()->putData (rsmpl_out, outBytes);
free (rsmpl_out);
} else {
dcblocker_.process(in, in, toGetSamples);
getMainBuffer()->putData (in, toGetBytes);
Manager::instance().getMainBuffer()->putData (in, toGetBytes);
}
end:
......@@ -565,10 +565,10 @@ void AlsaLayer::playback(int maxSamples)
{
unsigned short spkrVolume = Manager::instance().getSpkrVolume();
unsigned int mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
int toGet = getMainBuffer()->availForGet();
int toGet = Manager::instance().getMainBuffer()->availForGet();
int toPut = maxSamples * sizeof(SFLDataFormat);
if (toGet <= 0) { // no audio available, play tone or silence
......@@ -602,7 +602,7 @@ void AlsaLayer::playback(int maxSamples)
toGet = maxNbBytesToGet;
SFLDataFormat *out = (SFLDataFormat*) malloc (toGet);
getMainBuffer()->getData (out, toGet);
Manager::instance().getMainBuffer()->getData (out, toGet);
adjustVolume(out, toGet / sizeof(SFLDataFormat), spkrVolume);
if (resample) {
......@@ -644,7 +644,7 @@ void AlsaLayer::audioCallback (void)
write (out, toGet, playbackHandle_);
free (out);
// Consume the regular one as well (same amount of bytes)
getMainBuffer()->discard (toGet);
Manager::instance().getMainBuffer()->discard (toGet);
} else {
// regular audio data
playback(playbackAvailSmpl);
......
......@@ -56,7 +56,7 @@ void AudioLayer::flushMain (void)
{
ost::MutexLock guard (mutex_);
// should pass call id
getMainBuffer()->flushAllBuffers();
Manager::instance().getMainBuffer()->flushAllBuffers();
}
void AudioLayer::flushUrgent (void)
......
......@@ -111,18 +111,6 @@ class AudioLayer
return audioSampleRate_;
}
/**
* Get a pointer to the application MainBuffer class.
*
* In order to send signal to other parts of the application, one must pass through the mainbuffer.
* Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl.
*
* @return MainBuffer* a pointer to the MainBuffer instance
*/
MainBuffer* getMainBuffer (void) const {
return Manager::instance().getMainBuffer();
}
/**
* Get the mutex lock for the entire audio layer
*/
......
......@@ -434,7 +434,7 @@ void PulseLayer::writeToSpeaker (void)
urgentRingBuffer_.Get (data, urgentBytes);
pa_stream_write (s, data, urgentBytes, NULL, 0, PA_SEEK_RELATIVE);
// Consume the regular one as well (same amount of bytes)
getMainBuffer()->discard (urgentBytes);
Manager::instance().getMainBuffer()->discard (urgentBytes);
return;
}
......@@ -450,7 +450,7 @@ void PulseLayer::writeToSpeaker (void)
flushUrgent(); // flush remaining samples in _urgentRingBuffer
size_t availSamples = getMainBuffer()->availForGet() / sizeof(SFLDataFormat);
size_t availSamples = Manager::instance().getMainBuffer()->availForGet() / sizeof(SFLDataFormat);
if (availSamples == 0) {
pa_stream_begin_write(s, &data, &bytes);
memset(data, 0, bytes);
......@@ -458,7 +458,7 @@ void PulseLayer::writeToSpeaker (void)
return;
}
unsigned int mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
// how much samples we can write in the output
......@@ -479,7 +479,7 @@ void PulseLayer::writeToSpeaker (void)
size_t inBytes = inSamples * sizeof (SFLDataFormat);
pa_stream_begin_write(s, &data, &inBytes);
getMainBuffer()->getData (data, inBytes);
Manager::instance().getMainBuffer()->getData (data, inBytes);
if (resample) {
SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (outBytes);
......@@ -502,7 +502,7 @@ void PulseLayer::readFromMic (void)
return;
}
unsigned int mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
if (resample) {
double resampleFactor = (double) audioSampleRate_ / mainBufferSampleRate;
......@@ -520,7 +520,7 @@ void PulseLayer::readFromMic (void)
converter_->resample((SFLDataFormat*)data, mic_buffer_, mainBufferSampleRate, audioSampleRate_, samples);
dcblocker_.process(mic_buffer_, resample ? mic_buffer_ : (SFLDataFormat*)data, samples);
getMainBuffer()->putData(mic_buffer_, bytes);
Manager::instance().getMainBuffer()->putData(mic_buffer_, bytes);
if (pa_stream_drop (record_->pulseStream()) < 0)
_error ("Audio: Error: capture stream drop failed: %s" , pa_strerror (pa_context_errno (context_)));
......
......@@ -72,17 +72,10 @@ namespace {
}
}
IAXCall::IAXCall (const std::string& id, Call::CallType type) : Call (id, type), _session (NULL)
IAXCall::IAXCall (const std::string& id, Call::CallType type) : Call (id, type), session (NULL)
{
}
void
IAXCall::setFormat (int format)
{
_format = format;
setAudioCodec(ASTFormatToCodec(format));
}
int
IAXCall::getSupportedFormat (const std::string &accountID) const
{
......@@ -118,7 +111,7 @@ int IAXCall::getFirstMatchingFormat (int needles, const std::string &accountID)
return 0;
}
int IAXCall::getAudioCodec()
int IAXCall::getAudioCodec(void)
{
return _audioCodec;
return ASTFormatToCodec(format);
}
......@@ -50,38 +50,6 @@ class IAXCall : public Call
*/
IAXCall (const std::string& id, Call::CallType type);
/**
* @return iax_session* The session pointer or NULL
*/
iax_session* getSession() const {
return _session;
}
/**
* Set the session pointer
* @param session the session pointer to assign
*/
void setSession (iax_session* session) {
_session = session;
}
/**
* Set format (one single bit)
* This function sets the _audioCodec variable with the correct
* codec.
* @param format The format representing the codec
*/
void setFormat (int format);
/**
* Get format for the voice codec used
* @return int Bitmask for codecs defined in iax/frame.h
*/
int getFormat() const {
return _format;
}
/**
* @return int The bitwise list of supported formats
*/
......@@ -102,32 +70,10 @@ class IAXCall : public Call
*/
int getFirstMatchingFormat (int needles, const std::string &accountID) const;
/**
* Return audio codec [mutex protected]
* @return int The payload of the codec
*/
int getAudioCodec();
private:
/** Each call is associated with an iax_session */
iax_session* _session;
int getAudioCodec(void);
/**
* Set the audio codec used. [not protected]
* @param audioCodec The payload of the codec
*/
void setAudioCodec (int audioCodec) {
_audioCodec = audioCodec;
}
/** Codec pointer */
int _audioCodec;
/**
* Format currently in use in the conversation,
* sent in each outgoing voice packet.
*/
int _format;
int format;
iax_session* session;
};
#endif
This diff is collapsed.
......@@ -36,12 +36,12 @@
#include <iax-client.h>
#include "audio/codecs/audiocodec.h" // for DEC_BUFFER_SIZE
#include "global.h"
#include "audio/samplerateconverter.h"
namespace sfl {
class InstantMessaging;
}
class SamplerateConverter;
class EventThread;
class IAXCall;
......@@ -164,10 +164,8 @@ class IAXVoIPLink : public VoIPLink
/**
* Refuse a call
* @param id The ID of the call
* @return bool true on success
* false otherwise
*/
virtual bool refuse (const std::string& id);
virtual void refuse (const std::string& id);
/**
* Send DTMF
......@@ -185,11 +183,6 @@ class IAXVoIPLink : public VoIPLink
*/
virtual std::string getCurrentCodecName(Call *c) const;
public: // iaxvoiplink only
void updateAudiolayer (void);
private:
/*
* Decode the message count IAX send.
......@@ -208,11 +201,6 @@ class IAXVoIPLink : public VoIPLink
*/
IAXCall* getIAXCall (const std::string& id);
/**
* Delete every call
*/
void terminateIAXCall();
/**
* Find a iaxcall by iax session number
* @param session an iax_session valid pointer
......@@ -255,7 +243,7 @@ class IAXVoIPLink : public VoIPLink
* Send an outgoing call invite to iax
* @param call An IAXCall pointer
*/
bool iaxOutgoingInvite (IAXCall* call);
void iaxOutgoingInvite (IAXCall* call);
/** Threading object */
EventThread* evThread_;
......@@ -272,17 +260,13 @@ class IAXVoIPLink : public VoIPLink
* iax_stuff inside this class. */
ost::Mutex mutexIAX_;
/** Connection to audio card/device */
AudioLayer* audiolayer_;
/** encoder/decoder/resampler buffers */
SFLDataFormat decData[DEC_BUFFER_SIZE];
SFLDataFormat resampledData[DEC_BUFFER_SIZE];
unsigned char encodedData[DEC_BUFFER_SIZE];
int converterSamplingRate_;
/** Sample rate converter object */
SamplerateConverter* converter_;
SamplerateConverter converter_;
/** Whether init() was called already or not
* This should be used in init() and terminate(), to
......
......@@ -585,10 +585,8 @@ bool ManagerImpl::attendedTransfer(const std::string& transferID, const std::str
}
//THREAD=Main : Call:Incoming
bool ManagerImpl::refuseCall (const std::string& id)
void ManagerImpl::refuseCall (const std::string& id)
{
bool returnValue;
stopTone();
if (getCallList().size() <= 1) {
......@@ -600,31 +598,25 @@ bool ManagerImpl::refuseCall (const std::string& id)
/* Direct IP to IP call */
if (getConfigFromCall (id) == Call::IPtoIP)
returnValue = SIPVoIPLink::instance ()-> refuse (id);
SIPVoIPLink::instance()->refuse (id);
else {
/* Classic call, attached to an account */
std::string accountid = getAccountFromCall (id);
if (accountid.empty())
return false;
return;
returnValue = getAccountLink (accountid)->refuse (id);
getAccountLink(accountid)->refuse(id);
removeCallAccount (id);
}
// if the call was outgoing or established, we didn't refuse it
// so the method did nothing
if (returnValue) {
removeWaitingCall (id);
_dbus.getCallManager()->callStateChanged (id, "HUNGUP");
}
removeWaitingCall(id);
_dbus.getCallManager()->callStateChanged(id, "HUNGUP");
// Disconnect streams
removeStream(id);
getMainBuffer()->stateInfo();
return returnValue;
}
Conference*
......@@ -1361,8 +1353,6 @@ bool ManagerImpl::incomingCallWaiting ()
void ManagerImpl::addWaitingCall (const std::string& id)
{
_info ("Manager: Add waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall);
ost::MutexLock m(_waitingCallMutex);
_waitingCall.insert (id);
_nbIncomingWaitingCall++;
......@@ -1370,12 +1360,8 @@ void ManagerImpl::addWaitingCall (const std::string& id)
void ManagerImpl::removeWaitingCall (const std::string& id)
{
_info ("Manager: Remove waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall);
ost::MutexLock m(_waitingCallMutex);
// should return more than 1 if it erase a call
if (_waitingCall.erase (id))
if (_waitingCall.erase(id))
_nbIncomingWaitingCall--;
}
......@@ -1388,17 +1374,14 @@ bool ManagerImpl::isWaitingCall (const std::string& id)
// Management of event peer IP-phone
////////////////////////////////////////////////////////////////////////////////
// SipEvent Thread
bool ManagerImpl::incomingCall (Call* call, const std::string& accountId)
void ManagerImpl::incomingCall (Call* call, const std::string& accountId)
{
assert(call);
stopTone();
_debug ("Manager: Incoming call %s for account %s", call->getCallId().data(), accountId.c_str());
associateCallToAccount (call->getCallId(), accountId);
// If account is null it is an ip to ip call
if (accountId.empty())
if (accountId == "")
associateConfigToCall (call->getCallId(), Call::IPtoIP);
else {
// strip sip: which is not required and bring confusion with ip to ip calls
......@@ -1407,45 +1390,26 @@ bool ManagerImpl::incomingCall (Call* call, const std::string& accountId)
size_t startIndex = peerNumber.find ("sip:");
if (startIndex != std::string::npos) {
std::string strippedPeerNumber = peerNumber.substr (startIndex + 4);
call->setPeerNumber (strippedPeerNumber);
}
if (startIndex != std::string::npos)
call->setPeerNumber (peerNumber.substr (startIndex + 4));
}
if (!hasCurrentCall()) {
_debug ("Manager: Has no current call start ringing");
call->setConnectionState (Call::Ringing);
ringtone (accountId);
} else
_debug ("Manager: has current call, beep in current audio stream");
}
addWaitingCall (call->getCallId());
std::string from(call->getPeerName());
std::string number(call->getPeerNumber());
std::string display_name(call->getDisplayName());
if (not from.empty() and not number.empty()) {
from.append (" <");
from.append (number);
from.append (">");
} else if (from.empty()) {
from.append ("<");
from.append (number);
from.append (">");
}
/* Broadcast a signal over DBus */
_debug ("Manager: From: %s, Number: %s, Display Name: %s", from.c_str(), number.c_str(), display_name.c_str());
if (not from.empty() and not number.empty())
from += " ";
std::string display(display_name);
display.append(" ");
display.append(from);
from += "<" + number + ">";
_dbus.getCallManager()->incomingCall(accountId, call->getCallId(), display);
return true;
_dbus.getCallManager()->incomingCall(accountId, call->getCallId(), call->getDisplayName() + " " + from);
}
......
......@@ -231,7 +231,7 @@ class ManagerImpl
* Refuse the call
* @param id The call identifier
*/
bool refuseCall (const std::string& id);
void refuseCall (const std::string& id);
/**
* Create a new conference given two participant
......@@ -365,9 +365,8 @@ class ManagerImpl
* and notify user
* @param call A call pointer
* @param accountId an account id
* @return bool True if the call was added correctly
*/
bool incomingCall (Call* call, const std::string& accountId);
void incomingCall (Call* call, const std::string& accountId);
/**
* Notify the user that the recipient of the call has answered and the put the
......
......@@ -667,28 +667,26 @@ bool SIPVoIPLink::attendedTransfer(const std::string& id, const std::string& to)
return transferCommon(getSIPCall(id), &dst);
}
bool
void
SIPVoIPLink::refuse (const std::string& id)
{
SIPCall *call = getSIPCall (id);
if (!call->isIncoming() or call->getConnectionState() == Call::Connected)
return false;
return;
call->getAudioRtp()->stop();
pjsip_tx_data *tdata;
if (pjsip_inv_end_session (call->inv, PJSIP_SC_DECLINE, NULL, &tdata) != PJ_SUCCESS)
return false;
return;
if (pjsip_inv_send_msg (call->inv, tdata) != PJ_SUCCESS)
return false;
return;
// Make sure the pointer is NULL in callbacks
call->inv->mod_data[_mod_ua.id] = NULL;
removeCall (id);
return true;
}
std::string
......@@ -1730,8 +1728,12 @@ static pj_bool_t transaction_request_cb (pjsip_rx_data *rdata)
call->getAudioRtp()->start (static_cast<sfl::AudioCodec *>(audiocodec));
pjsip_dialog* dialog;
if (pjsip_dlg_create_uas (pjsip_ua_instance(), rdata, NULL, &dialog) != PJ_SUCCESS)
goto fail;
if (pjsip_dlg_create_uas (pjsip_ua_instance(), rdata, NULL, &dialog) != PJ_SUCCESS) {
delete call;
pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
return false;
}
pjsip_inv_create_uas (dialog, rdata, call->getLocalSDP()->getLocalSdpSession(), 0, &call->inv);
......@@ -1767,18 +1769,11 @@ static pj_bool_t transaction_request_cb (pjsip_rx_data *rdata)
call->setConnectionState (Call::Ringing);
if (!Manager::instance().incomingCall (call, account_id))
goto fail;
Manager::instance().incomingCall (call, account_id);
Manager::instance().getAccountLink (account_id)->addCall (call);
}
return true;
fail:
delete call;
pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
return false;
}
static pj_bool_t transaction_response_cb (pjsip_rx_data *rdata)
......
......@@ -164,9 +164,8 @@ class SIPVoIPLink : public VoIPLink
/**
* Refuse the call
* @param id The call identifier
* @return bool True on success
*/
virtual bool refuse (const std::string& id);
virtual void refuse (const std::string& id);
/**
* Send DTMF refering to account configuration
......
......@@ -148,9 +148,8 @@ class VoIPLink
/**
* Refuse incoming call
* @param id The call identifier
* @return bool True on success
*/
virtual bool refuse (const std::string& id) = 0;
virtual void refuse (const std::string& id) = 0;
/**
* Send DTMF
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment