Commit 014cf030 authored by Emmanuel Lepage's avatar Emmanuel Lepage
parents 8f2b65ee 130f92bc
......@@ -52,9 +52,12 @@
# define wcsicmp _wcsicmp
# define wcsnicmp _wcsnicmp
#else
#ifndef stricmp
# define stricmp strcasecmp
#endif
#ifndef strnicmp
# define strnicmp strncasecmp
#endif
# if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
# error "Implement Unicode string functions"
# endif
......
......@@ -92,15 +92,6 @@ static cipher_name_t cipher_names[] =
{PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA, "SSL_FORTEZZA_KEA_WITH_NULL_SHA"},
{PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,"SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"},
{PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"},
/* SSLv2 */
{PJ_SSL_CK_RC4_128_WITH_MD5, "SSL_CK_RC4_128_WITH_MD5"},
{PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5, "SSL_CK_RC4_128_EXPORT40_WITH_MD5"},
{PJ_SSL_CK_RC2_128_CBC_WITH_MD5, "SSL_CK_RC2_128_CBC_WITH_MD5"},
{PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5"},
{PJ_SSL_CK_IDEA_128_CBC_WITH_MD5, "SSL_CK_IDEA_128_CBC_WITH_MD5"},
{PJ_SSL_CK_DES_64_CBC_WITH_MD5, "SSL_CK_DES_64_CBC_WITH_MD5"},
{PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5, "SSL_CK_DES_192_EDE3_CBC_WITH_MD5"}
};
......
......@@ -70,7 +70,6 @@ static const char *const CONFIG_ACCOUNT_TYPE = "Account.type";
static const char *const CONFIG_ACCOUNT_ALIAS = "Account.alias";
static const char *const CONFIG_ACCOUNT_MAILBOX = "Account.mailbox";
static const char *const CONFIG_ACCOUNT_ENABLE = "Account.enable";
static const char *const CONFIG_ACCOUNT_RESOLVE_ONCE = "Account.resolveOnce";
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE = "Account.expire";
static const char *const CONFIG_CREDENTIAL_NUMBER = "Credential.count";
static const char *const ACCOUNT_DTMF_TYPE = "Account.dtmfType";
......
......@@ -158,25 +158,17 @@ void AudioRtpFactory::start (AudioCodec* audiocodec)
void AudioRtpFactory::stop (void)
{
ost::MutexLock mutex (_audioRtpThreadMutex);
_info ("AudioRtpFactory: Stopping audio rtp session");
if (_rtpSession == NULL) {
_debug ("AudioRtpFactory: Rtp session already deleted");
if (_rtpSession == NULL)
return;
}
try {
if (_rtpSession->getAudioRtpType() == Sdes) {
localContext = static_cast<AudioSrtpSession *> (_rtpSession)->_localCryptoCtx;
remoteContext = static_cast<AudioSrtpSession *> (_rtpSession)->_remoteCryptoCtx;
}
if (_rtpSession->getAudioRtpType() == Sdes) {
localContext = static_cast<AudioSrtpSession *> (_rtpSession)->_localCryptoCtx;
remoteContext = static_cast<AudioSrtpSession *> (_rtpSession)->_remoteCryptoCtx;
}
delete _rtpSession;
_rtpSession = NULL;
} catch (...) {
_debug ("AudioRtpFactory: Error: Exception caught when stopping the audio rtp session");
throw AudioRtpFactoryException ("AudioRtpFactory: Error: caught exception in AudioRtpFactory::stop");
}
delete _rtpSession;
_rtpSession = NULL;
}
int AudioRtpFactory::getSessionMedia()
......@@ -192,8 +184,6 @@ int AudioRtpFactory::getSessionMedia()
void AudioRtpFactory::updateSessionMedia (AudioCodec *audiocodec)
{
_info ("AudioRtpFactory: Updating session media");
if (_rtpSession == NULL) {
throw AudioRtpFactoryException ("AudioRtpFactory: Error: _rtpSession was null when trying to update IP address");
}
......@@ -202,8 +192,6 @@ void AudioRtpFactory::updateSessionMedia (AudioCodec *audiocodec)
void AudioRtpFactory::updateDestinationIpAddress (void)
{
_info ("AudioRtpFactory: Updating IP address");
if (_rtpSession == NULL) {
throw AudioRtpFactoryException ("AudioRtpFactory: Error: RtpSession was null when trying to update IP address");
}
......@@ -244,9 +232,7 @@ void AudioRtpFactory::setDtmfPayloadType(unsigned int payloadType)
void AudioRtpFactory::sendDtmfDigit (int digit)
{
_rtpSession->putDtmfEvent (digit);
_rtpSession->putDtmfEvent(digit);
}
}
......@@ -30,6 +30,7 @@
#include "AudioRtpRecordHandler.h"
#include <fstream>
#include "sip/sipcall.h"
#include "audio/audiolayer.h"
#include "manager.h"
......
......@@ -36,7 +36,7 @@ using std::ptrdiff_t;
#include <ccrtp/rtp.h>
#include <list>
#include "sip/sipcall.h"
class SIPCall;
#include "audio/codecs/audiocodec.h"
#include "audio/samplerateconverter.h"
#include "audio/noisesuppress.h"
......@@ -105,7 +105,7 @@ class AudioRtpRecord
class AudioRtpRecordHandler
{
public:
AudioRtpRecordHandler (SIPCall *ca);
AudioRtpRecordHandler(SIPCall *);
virtual ~AudioRtpRecordHandler();
/**
......
......@@ -60,15 +60,11 @@ AudioRtpSession::AudioRtpSession (SIPCall * sipcall, RtpMethod type, ost::RTPDat
AudioRtpSession::~AudioRtpSession()
{
_info ("AudioRtpSession: Delete AudioRtpSession instance");
_queue->disableStack();
}
void AudioRtpSession::updateSessionMedia (AudioCodec *audioCodec)
{
_debug ("AudioSymmetricRtpSession: Update session media");
// Update internal codec for this session
int lastSamplingRate = _audioRtpRecord._codecSampleRate;
setSessionMedia(audioCodec);
......@@ -84,9 +80,6 @@ void AudioRtpSession::updateSessionMedia (AudioCodec *audioCodec)
void AudioRtpSession::setSessionMedia (AudioCodec *audioCodec)
{
_debug ("AudioSymmetricRtpSession: Set session media");
// set internal codec info for this session
setRtpMedia (audioCodec);
// store codec info locally
......
......@@ -87,51 +87,26 @@ Call::getState()
std::string
Call::getStateStr ()
{
CallState state = getState();
ConnectionState connection = getConnectionState ();
CallType type = _type;
std::string state_str;
switch (state) {
switch (getState()) {
case Active:
switch (connection) {
case Ringing:
(type == Incoming) ? state_str = "INCOMING":state_str = "RINGING";
break;
switch (getConnectionState()) {
case Ringing: return isIncoming() ? "INCOMING" : "RINGING";
case Connected:
default:
isRecording() ? state_str = "RECORD" : state_str = "CURRENT";
break;
default: return isRecording() ? "RECORD" : "CURRENT";
}
case Hold:
state_str = "HOLD";
break;
case Busy:
state_str = "BUSY";
break;
case Hold: return "HOLD";
case Busy: return "BUSY";
case Inactive:
switch (connection) {
case Ringing:
(type == Incoming) ? state_str = "INCOMING":state_str = "RINGING";
break;
case Connected:
state_str = "CURRENT";
break;
default:
state_str = "INACTIVE";
break;
switch (getConnectionState()) {
case Ringing: return isIncoming() ? "INCOMING" : "RINGING";
case Connected: return "CURRENT";
default: return "INACTIVE";
}
break;
case Conferencing:
state_str = "CONFERENCING";
break;
case Conferencing: return "CONFERENCING";
case Refused:
case Error:
default:
state_str = "FAILURE";
break;
default: return "FAILURE";
}
return state_str;
}
......@@ -152,36 +127,20 @@ Call::getLocalAudioPort()
bool
Call::setRecording()
{
_debug ("Call: Set recording");
bool recordStatus = Recordable::recAudio.isRecording();
Recordable::recAudio.setRecording();
MainBuffer *mbuffer = Manager::instance().getMainBuffer();
std::string process_id = Recordable::recorder.getRecorderID();
// Start recording
if (!recordStatus) {
_debug ("Call: Call not recording yet, set ringbuffers");
MainBuffer *mbuffer = Manager::instance().getMainBuffer();
std::string process_id = Recordable::recorder.getRecorderID();
mbuffer->bindHalfDuplexOut (process_id, _id);
mbuffer->bindHalfDuplexOut (process_id);
Recordable::recorder.start();
}
// Stop recording
else {
_debug ("Call: Stop recording");
MainBuffer *mbuffer = Manager::instance().getMainBuffer();
std::string process_id = Recordable::recorder.getRecorderID();
} else {
mbuffer->unBindHalfDuplexOut (process_id, _id);
mbuffer->unBindHalfDuplexOut (process_id);
}
Manager::instance().getMainBuffer()->stateInfo();
......
......@@ -170,7 +170,7 @@ class Call: public Recordable
* false otherwise
*/
bool isIncoming() {
return (_type == Incoming) ? true : false;
return _type == Incoming;
}
/**
......
......@@ -33,6 +33,7 @@
#include "global.h"
#include "callmanager.h"
#include "sip/sipcall.h"
#include "sip/sipvoiplink.h"
#include "audio/audiortp/AudioRtpFactory.h"
#include "audio/audiortp/AudioZrtpSession.h"
......@@ -366,26 +367,15 @@ sfl::AudioZrtpSession * CallManager::getAudioZrtpSession (const std::string& cal
SIPCall *call;
try {
call = link->getSIPCall (callID);
call = link->getSIPCall(callID);
}
catch (const VoipLinkException &e) {
throw CallManagerException("Call id " + callID + " is not valid");
}
sfl::AudioRtpFactory * audioRtp = NULL;
audioRtp = call->getAudioRtp();
if (!audioRtp) {
throw CallManagerException("Failed to get AudioRtpFactory");
}
sfl::AudioZrtpSession * zSession = NULL;
zSession = audioRtp->getAudioZrtpSession();
if (!zSession) {
sfl::AudioZrtpSession * zSession = call->getAudioRtp()->getAudioZrtpSession();
if (!zSession)
throw CallManagerException("Failed to get AudioZrtpSession");
}
return zSession;
}
......
......@@ -33,6 +33,8 @@
void UrlHook::runAction (std::string command, std::string args)
{
if (args.empty())
return;
//FIXME : use fork and execve, so no need to escape shell arguments
std::string cmd = command + "\"" + args + "\" &";
system(cmd.c_str());
......
......@@ -170,7 +170,7 @@ IAXVoIPLink::getEvent()
{
ost::MutexLock m(mutexIAX_);
while ((event = iax_get_event (IAX_NONBLOCKING)) != NULL) {
// If we received an 'ACK', libiax2 tells apps to ignore them.
// If we received an 'ACK', libiax2 tells apps to ignore them.
if (event->etype == IAX_EVENT_NULL)
continue;
......@@ -178,24 +178,20 @@ IAXVoIPLink::getEvent()
if (call)
iaxHandleCallEvent (event, call);
else if (event->session && event->session == regSession_) {
// This is a registration session, deal with it
else if (event->session && event->session == regSession_) // This is a registration session, deal with it
iaxHandleRegReply (event);
} else {
// We've got an event before it's associated with any call
else // We've got an event before it's associated with any call
iaxHandlePrecallEvent (event);
}
iax_event_free (event);
}
free(event);
}
sendAudioFromMic();
// thread wait 3 millisecond
evThread_->sleep(3);
free (event);
}
void
......@@ -432,11 +428,12 @@ IAXVoIPLink::offhold (const std::string& id)
call->setState (Call::Active);
}
bool
void
IAXVoIPLink::transfer (const std::string& id, const std::string& to)
{
IAXCall* call = getIAXCall (id);
CHK_VALID_CALL;
if (!call)
return;
char callto[to.length() +1];
strcpy (callto, to.c_str());
......@@ -444,11 +441,6 @@ IAXVoIPLink::transfer (const std::string& id, const std::string& to)
mutexIAX_.enterMutex();
iax_transfer (call->getSession(), callto);
mutexIAX_.leaveMutex();
return true;
// should we remove it?
// removeCall(id);
}
bool
......@@ -474,36 +466,29 @@ IAXVoIPLink::refuse (const std::string& id)
}
bool
void
IAXVoIPLink::carryingDTMFdigits (const std::string& id, char code)
{
IAXCall* call = getIAXCall (id);
CHK_VALID_CALL;
mutexIAX_.enterMutex();
iax_send_dtmf (call->getSession(), code);
mutexIAX_.leaveMutex();
return true;
if (call) {
mutexIAX_.enterMutex();
iax_send_dtmf (call->getSession(), code);
mutexIAX_.leaveMutex();
}
}
bool
void
IAXVoIPLink::sendTextMessage (sfl::InstantMessaging *module,
const std::string& callID, const std::string& message,
const std::string& /*from*/)
{
IAXCall* call = getIAXCall (callID);
CHK_VALID_CALL;
if (!call)
return;
// Must active the mutex for this session
mutexIAX_.enterMutex();
module->send_iax_message (call->getSession(), callID, message.c_str());
// iax_send_text (call->getSession(), message.c_str());
mutexIAX_.leaveMutex();
return true;
}
......@@ -649,28 +634,17 @@ IAXVoIPLink::iaxHandleCallEvent (iax_event* event, IAXCall* call)
break;
case IAX_IE_MSGCOUNT:
break;
case IAX_EVENT_TIMEOUT:
case IAX_EVENT_PONG:
default:
break;
case IAX_EVENT_URL:
if (Manager::instance().getConfigString (HOOKS, URLHOOK_IAX2_ENABLED) == "1") {
if (*event->data) {
_debug ("> IAX_EVENT_URL received: %s", event->data);
UrlHook::runAction (Manager::instance().getConfigString (HOOKS, URLHOOK_COMMAND), (char*) event->data);
}
}
if (Manager::instance().getConfigString (HOOKS, URLHOOK_IAX2_ENABLED) == "1")
UrlHook::runAction (Manager::instance().getConfigString (HOOKS, URLHOOK_COMMAND), (char*) event->data);
break;
case IAX_EVENT_TIMEOUT:
break;
default:
_debug ("iaxHandleCallEvent: Unknown event type (in call event): %d", event->etype);
}
}
......
......@@ -150,10 +150,8 @@ class IAXVoIPLink : public VoIPLink
* Transfer a call
* @param id The ID of the call
* @param to The recipient of the transfer
* @return bool true on success
* false otherwise
*/
virtual bool transfer (const std::string& id, const std::string& to);
virtual void transfer (const std::string& id, const std::string& to);
/**
* Perform attended transfer
......@@ -175,13 +173,11 @@ class IAXVoIPLink : public VoIPLink
* Send DTMF
* @param id The ID of the call
* @param code The code of the DTMF
* @return bool true on success
* false otherwise
*/
virtual bool carryingDTMFdigits (const std::string& id, char code);
virtual void carryingDTMFdigits (const std::string& id, char code);
virtual bool sendTextMessage (sfl::InstantMessaging *module, const std::string& callID, const std::string& message, const std::string& from);
virtual void sendTextMessage (sfl::InstantMessaging *module, const std::string& callID, const std::string& message, const std::string& from);
/**
* Return the codec protocol used for this call
......
......@@ -36,43 +36,17 @@
namespace sfl
{
static inline char* duplicateString (char dst[], const char src[], size_t len)
{
memcpy (dst, src, len);
dst[len] = 0;
return dst;
}
static void XMLCALL startElementCallback (void *userData, const char *name, const char **atts)
{
if (strcmp (name, "entry"))
return;
char attribute[100];
char value[100];
const char **att;
// _debug ("InstantMessaging: StartElement Callback: %s", name);
if (strcmp (name, "entry") == 0) {
sfl::InstantMessaging::UriList *list = static_cast<sfl::InstantMessaging::UriList *> (userData);
sfl::InstantMessaging::UriEntry entry = sfl::InstantMessaging::UriEntry();
for (att = atts; *att; att += 2) {
const char **val = att+1;
duplicateString (attribute, *att, strlen (*att));
duplicateString (value, *val, strlen (*val));
// _debug ("InstantMessaging: attribute: %s, value: %s", attribute, value);
sfl::InstantMessaging::UriEntry entry = sfl::InstantMessaging::UriEntry();
entry.insert (std::pair<std::string, std::string> (std::string (attribute), std::string (value)));
}
list->push_back (entry);
}
for (const char **att = atts; *att; att += 2)
entry.insert (std::pair<std::string, std::string> (*att, *(att+1)));
(static_cast<sfl::InstantMessaging::UriList *> (userData))->push_back(entry);
}
static void XMLCALL endElementCallback (void * /*userData*/, const char * /*name*/)
......@@ -80,47 +54,15 @@ static void XMLCALL endElementCallback (void * /*userData*/, const char * /*name
}
InstantMessaging::InstantMessaging()
: imFiles ()
, messageMaxSize (MAXIMUM_MESSAGE_LENGTH) {}
InstantMessaging::InstantMessaging() {}
InstantMessaging::~InstantMessaging() {}
bool InstantMessaging::init ()
{
return true;
}
int InstantMessaging::openArchive (std::string& id)
{
// Create a new file stream
std::ofstream File (id.c_str (), std::ios::out | std::ios::app);
imFiles[id] = &File;
// Attach it to the call ID
return (int) imFiles.size ();
}
int InstantMessaging::closeArchive (std::string& id)
{
// Erase it from the map
imFiles.erase (id);
return (int) imFiles.size ();
}
bool InstantMessaging::saveMessage (const std::string& message, const std::string& author, const std::string& id, int mode)
{
// We need here to write the text message in the right file.
// We will use the Call ID
std::ofstream File;
std::string filename = "im:";
filename.append (id);
std::string filename = "im:" + id;
File.open (filename.c_str (), (std::_Ios_Openmode) mode);
if (!File.good () || !File.is_open ())
......@@ -132,209 +74,74 @@ bool InstantMessaging::saveMessage (const std::string& message, const std::strin
return true;
}
std::string InstantMessaging::receive (const std::string& message, const std::string& /*author*/, const std::string& /*id*/)
{
// We just receive a TEXT message. Before sent it to the recipient, we must assure that the message is complete.
// We should use a queue to push these messages in
_debug ("New message : %s", message.c_str ());
// TODO Security check
// TODO String cleaning
// Archive the message
// TODO Deactivate this for the momment, this is an extra feature.
// this->saveMessage (message, author, id);
return message;