From 05ac30a59e64418b3d86661863b21ca24e47cced Mon Sep 17 00:00:00 2001 From: llea <llea> Date: Thu, 14 Jul 2005 16:11:33 +0000 Subject: [PATCH] Fix tone by Jerome Oufella --- ChangeLog | 6 + src/audio/audiolayer.cpp | 2 +- src/audio/ringbuffer.cpp | 4 +- src/audio/tonegenerator.cpp | 86 ++- src/gui/qt/qtGUImainwindow.cpp | 5 +- src/manager.cpp | 864 ---------------------------- src/sipvoiplink.cpp | 4 +- utilspp/lifetime_default.hpp | 56 ++ utilspp/lifetime_with_longevity.hpp | 59 ++ utilspp/lifetime_with_longevity.inl | 67 +++ utilspp/null_type.hpp | 33 ++ utilspp/private_members.hpp | 98 ++++ utilspp/private_members.inl | 31 + utilspp/singleton_holder.inl~ | 124 ---- utilspp/threading_single.hpp | 74 +++ 15 files changed, 497 insertions(+), 1016 deletions(-) delete mode 100644 src/manager.cpp create mode 100644 utilspp/lifetime_default.hpp create mode 100644 utilspp/lifetime_with_longevity.hpp create mode 100644 utilspp/lifetime_with_longevity.inl create mode 100644 utilspp/null_type.hpp create mode 100644 utilspp/private_members.hpp create mode 100644 utilspp/private_members.inl delete mode 100644 utilspp/singleton_holder.inl~ create mode 100644 utilspp/threading_single.hpp diff --git a/ChangeLog b/ChangeLog index 9b838436c7..20cc6cab3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Jerome OUFELLA (13 July 2005) version 0.4 +- Fix tone. + +Jean-Philippe Barette-LaPierre (13 July 2005) version 0.4 +- Change "Manager" to a singleton + Laurielle LEA (13 July 2005) version 0.4 - Fix bug if network is not available. - Fix apply skin feature diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp index 6f110b7056..9fdf1278f4 100644 --- a/src/audio/audiolayer.cpp +++ b/src/audio/audiolayer.cpp @@ -148,7 +148,7 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer, } _urgentRingBuffer.Get(out, SAMPLES_SIZE(toGet)); - // Consume the regular one as well + // Consume the regular one as well (same amount of bytes) _mainSndRingBuffer.Discard(SAMPLES_SIZE(toGet)); } else { diff --git a/src/audio/ringbuffer.cpp b/src/audio/ringbuffer.cpp index 258e1d5108..71318875ba 100644 --- a/src/audio/ringbuffer.cpp +++ b/src/audio/ringbuffer.cpp @@ -10,6 +10,7 @@ overestimate. **********************************************************************/ +#include <iostream> //debug #include <assert.h> #include <stdlib.h> #include <string.h> @@ -138,8 +139,7 @@ RingBuffer::Get(void *buffer, int toCopy) { if (block > mBufferSize - mStart) block = mBufferSize - mStart; - bcopy (mBuffer + mStart, dest, block); - + bcopy (mBuffer + mStart, dest, block); dest += block; mStart = (mStart + block) % mBufferSize; toCopy -= block; diff --git a/src/audio/tonegenerator.cpp b/src/audio/tonegenerator.cpp index 8a62cf23c9..197eb880f5 100644 --- a/src/audio/tonegenerator.cpp +++ b/src/audio/tonegenerator.cpp @@ -20,7 +20,7 @@ #include <math.h> #include <iostream> #include <fstream> -#include <stdlib.h> +#include <stdlib.h> #include "audiolayer.h" #include "audiortp.h" @@ -55,19 +55,31 @@ void ToneThread::run (void) { int k; int spkrVolume; + bool started = false; + + // How long do 'size' samples play ? + unsigned int play_time = (size * 1000) / SAMPLING_RATE; + + // Create a new stereo buffer with the volume adjusted + spkrVolume = mngr->getSpkrVolume(); + for (int j = 0; j < size; j++) { + k = j*2; + buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j] * spkrVolume/100; + } + while (Manager::instance().getZonetone()) { - spkrVolume = Manager::instance().getSpkrVolume(); - // control volume + mono->stereo - for (int j = 0; j < size; j++) { - k = j*2; - buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j] * spkrVolume/100; + // Push the tone to the audio FIFO + Manager::instance().getAudioDriver()->mainSndRingBuffer().Put(buf_ctrl_vol, + SAMPLES_SIZE(size)); + + // The first iteration will start the audio stream if not already. + if (!started) { + started = true; + Manager::instance().getAudioDriver()->startStream(); } - if (Manager::instance().getAudioDriver()->mainSndRingBuffer().Len() == 0) { - Manager::instance().getAudioDriver()->mainSndRingBuffer().Put(buf_ctrl_vol, - SAMPLES_SIZE(size)); - } - Manager::instance().getAudioDriver()->startStream(); + // next iteration later, sound is playing. + this->sleep (play_time); } } @@ -164,7 +176,7 @@ ToneGenerator::buildTone (int idCountry, int idTones, int16* temp) { int byte = 0, byte_temp = 0; static int nbcomma = 0; - int16 *buffer = new int16[SIZEBUF]; + int16 *buffer = new int16[SIZEBUF]; //1kb int pos; string str(toneZone[idCountry][idTones]); @@ -172,35 +184,67 @@ ToneGenerator::buildTone (int idCountry, int idTones, int16* temp) { // Number of format sections for (int i = 0; i < nbcomma + 1; i++) { + // Sample string: "350+440" or "350+440/2000,244+655/2000" pos = str.find(','); - s = str.substr(0, pos); - pos = s.find('+'); + if (pos < 0) { // no comma found + pos = str.length(); + } + + s = str.substr(0, pos); // + + // The 1st frequency is before the first + + int pos_freq2; + pos_freq2 = pos = s.find('+'); + if (pos < 0) { + pos = s.length(); // no + found + } freq1 = atoi((s.substr(0, pos)).data()); - freq2 = atoi((s.substr(pos + 1, s.find('/'))).data()); + + int pos2 = s.find('/'); + if (pos2 < 0) { + pos2 = s.length(); + } + if (pos_freq2 < 0) { + // freq2 was not found + freq2 = 0; + } else { + // freq2 was found and is after the + + freq2 = atoi( s.substr(pos + 1, pos2).data() ); + } + pos = s.find('/'); - time = atoi((s.substr(pos + 1, s.length())).data()); + if (pos < 0) { + time = 0; // No time specified, tone will last forever. + } else { + time = atoi((s.substr(pos + 1, s.length())).data()); + } - // Generate sinus, buffer is the result + // Generate SAMPLING_RATE samples of sinus, buffer is the result generateSin(freq1, freq2, buffer); // If there is time or if it's unlimited - if (time) { - byte = (SAMPLING_RATE*2*time)/1000; + if (time > 0) { + byte = (SAMPLING_RATE * 2 * time) / 1000; } else { byte = SAMPLING_RATE; } // To concatenate the different buffers for each section. + count = 0; for (int j = byte_temp * i; j < byte + (byte_temp * i); j++) { temp[j] = buffer[count++]; } byte_temp = byte; - count = 0; str = str.substr(str.find(',') + 1, str.length()); } + // Total number in final buffer - totalbytes = byte + (byte_temp * (nbcomma+1)); + if (byte != SAMPLING_RATE) { + totalbytes = byte + (byte_temp * (nbcomma+1)); + } else { + totalbytes = byte; + } delete[] buffer; } diff --git a/src/gui/qt/qtGUImainwindow.cpp b/src/gui/qt/qtGUImainwindow.cpp index 718b318f85..94edb06a61 100644 --- a/src/gui/qt/qtGUImainwindow.cpp +++ b/src/gui/qt/qtGUImainwindow.cpp @@ -1562,7 +1562,7 @@ QtGUIMainWindow::pressedKeySlot (int id) { int k, spkrVolume; int16* buf_ctrl_vol; - // Stop dial tone + // Stop dial tone because we started dialing. if (_dialtone) { dialtone(false); } @@ -1606,14 +1606,15 @@ QtGUIMainWindow::pressedKeySlot (int id) { buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = _buf[j] * spkrVolume/100; } - // Counters reset Manager::instance().getAudioDriver()->urgentRingBuffer().flush(); // Put buffer to urgentRingBuffer Manager::instance().getAudioDriver()->urgentRingBuffer().Put(buf_ctrl_vol, size * CHANNELS); + Manager::instance().getAudioDriver()->startStream(); Manager::instance().getAudioDriver()->sleep(pulselen); Manager::instance().getAudioDriver()->stopStream(); + Manager::instance().getAudioDriver()->urgentRingBuffer().flush(); delete[] buf_ctrl_vol; } diff --git a/src/manager.cpp b/src/manager.cpp deleted file mode 100644 index b233778872..0000000000 --- a/src/manager.cpp +++ /dev/null @@ -1,864 +0,0 @@ -/** - * Copyright (C) 2004-2005 Savoir-Faire Linux inc. - * Author : Laurielle Lea <laurielle.lea@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <errno.h> -#include <time.h> - -# include <sys/types.h> // mkdir(2) -# include <sys/stat.h> // mkdir(2) - -#include <sys/socket.h> // inet_ntoa() -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <cc++/thread.h> -#include <cstdlib> -#include <iostream> -#include <fstream> -#include <string> -#include <vector> - -#include "manager.h" -#include "audio/audiocodec.h" -#include "audio/audiolayer.h" -#include "audio/codecDescriptor.h" -#include "audio/ringbuffer.h" -#include "audio/tonegenerator.h" -#include "call.h" -#include "configuration.h" -#include "configurationtree.h" -#include "error.h" -#include "sipvoiplink.h" -#include "skin.h" -#include "user_cfg.h" -#include "voIPLink.h" -#include "gui/guiframework.h" - -using namespace std; -using namespace ost; - -device_t Manager::deviceParam; - -Manager::Manager (void) -{ - // initialize random generator - srand (time(NULL)); - - // Init private variables - _callVector = new CallVector(); - _voIPLinkVector = new VoIPLinkVector(); - _error = new Error(this); - _tone = new ToneGenerator(this); - - // Set a sip voip link by default - _voIPLinkVector->push_back(new SipVoIPLink(DFT_VOIP_LINK, this)); - - _nCalls = 0; - _nCodecs = 0; - _currentCallId = 0; - _startTime = 0; - _endTime = 0; - _path = ""; - _zonetone = false; - _congestion = false; - _ringtone = false; - _ringback = false; - _exist = 0; - _loaded = false; - - initConfigFile(); - _exist = createSettingsPath(); - if (_exist == 0) { - _debug("Cannot create config file in your home directory\n"); - } -} - -Manager::~Manager (void) -{ - delete _callVector; - delete _voIPLinkVector; - delete _error; - delete _tone; - delete _codecDescVector; - delete _audiodriverPA; -} - -void -Manager::init (void) -{ - if (_exist == 2) { - // If config-file doesn't exist, launch configuration setup - _gui->setup(); - } - initAudioCodec(); - - try { - selectAudioDriver(); - loaded(true); - } - catch (const portaudio::PaException &e) - { - displayErrorText(e.paErrorText()); - } - catch (const portaudio::PaCppException &e) - { - displayErrorText(e.what()); - } - catch (const exception &e) - { - displayErrorText(e.what()); - } - catch (...) - { - displayErrorText("An unknown exception occured."); - } - - _voIPLinkVector->at(DFT_VOIP_LINK)->init(); - - if (_voIPLinkVector->at(DFT_VOIP_LINK)->checkNetwork()) { - // If network is available - if (get_config_fields_int(SIGNALISATION, AUTO_REGISTER) == YES and - _exist == 1) { - if (registerVoIPLink() != 1) { - _debug("Registration failed\n"); - displayErrorText("Check your configuration fields"); - } - } - } -} - -void -Manager::setGui (GuiFramework* gui) -{ - _gui = gui; -} - -ToneGenerator* -Manager::getTonegenerator (void) -{ - return _tone; -} - -Error* -Manager::error (void) -{ - return _error; -} - -AudioLayer* -Manager::getAudioDriver(void) -{ - return _audiodriverPA; -} - -unsigned int -Manager::getNumberOfCalls (void) -{ - return _nCalls; -} - -void -Manager::setNumberOfCalls (unsigned int nCalls) -{ - _nCalls = nCalls; -} - -short -Manager::getCurrentCallId (void) -{ - return _currentCallId; -} - -void -Manager::setCurrentCallId (short currentCallId) -{ - _currentCallId = currentCallId; -} - -CallVector* -Manager::getCallVector (void) -{ - return _callVector; -} - -Call* -Manager::getCall (short id) -{ - if (id > 0 and _callVector->size() > 0) { - for (unsigned int i = 0; i < _nCalls; i++) { - if (_callVector->at(i)->getId() == id) { - return _callVector->at(i); - } - } - return NULL; - } else { - return NULL; - } -} - - -unsigned int -Manager::getNumberOfCodecs (void) -{ - return _nCodecs; -} - -void -Manager::setNumberOfCodecs (unsigned int nb_codec) -{ - _nCodecs = nb_codec; -} - -VoIPLinkVector* -Manager::getVoIPLinkVector (void) -{ - return _voIPLinkVector; -} - -CodecDescriptorVector* -Manager::getCodecDescVector (void) -{ - return _codecDescVector; -} - -void -Manager::pushBackNewCall (short id, enum CallType type) -{ - Call* call = new Call(this, id, type, _voIPLinkVector->at(DFT_VOIP_LINK)); - // Set the wanted voip-link (first of the list) - _callVector->push_back(call); -} - -void -Manager::deleteCall (short id) -{ - unsigned int i = 0; - while (i < _callVector->size()) { - if (_callVector->at(i)->getId() == id) { - _callVector->erase(_callVector->begin()+i); - return; - } else { - i++; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Management of events' IP-phone user -/////////////////////////////////////////////////////////////////////////////// -int -Manager::outgoingCall (const string& to) -{ - short id; - Call* call; - - id = generateNewCallId(); - pushBackNewCall(id, Outgoing); - - _debug("Outgoing Call with identifiant %d\n", id); - call = getCall(id); - if (call == NULL) - return 0; - - call->setStatus(string(TRYING_STATUS)); - call->setState(Progressing); - if (call->outgoingCall(id, to) == 0) { - return id; - } else { - return 0; - } -} - -int -Manager::hangupCall (short id) -{ - Call* call; - - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(HUNGUP_STATUS)); - call->setState(Hungup); - _mutex.enterMutex(); - _nCalls -= 1; - _mutex.leaveMutex(); - deleteCall(id); - if (getbRingback()) { - ringback(false); - } - return call->hangup(); -} - -int -Manager::cancelCall (short id) -{ - Call* call; - - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(HUNGUP_STATUS)); - call->setState(Hungup); - _mutex.enterMutex(); - _nCalls -= 1; - _mutex.leaveMutex(); - deleteCall(id); - if (getbRingback()) { - ringback(false); - } - return call->cancel(); -} - -int -Manager::answerCall (short id) -{ - Call* call; - - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(CONNECTED_STATUS)); - call->setState(Answered); - ringtone(false); - return call->answer(); -} - -int -Manager::onHoldCall (short id) -{ - Call* call; - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(ONHOLD_STATUS)); - call->setState(OnHold); - return call->onHold(); -} - -int -Manager::offHoldCall (short id) -{ - Call* call; - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(CONNECTED_STATUS)); - call->setState(OffHold); - return call->offHold(); -} - -int -Manager::transferCall (short id, const string& to) -{ - Call* call; - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(TRANSFER_STATUS)); - call->setState(Transfered); - if (call->transfer(to) != 0) { - return -1; - } else { - return 1; - } -} - -void -Manager::muteOn (short id) -{ - Call* call; - call = getCall(id); - if (call == NULL) - return; - call->setStatus(string(MUTE_ON_STATUS)); - call->setState(MuteOn); -} - -void -Manager::muteOff (short id) -{ - Call* call; - call = getCall(id); - if (call == NULL) - return; - call->setStatus(string(CONNECTED_STATUS)); - call->setState(MuteOff); -} - -int -Manager::refuseCall (short id) -{ - Call *call; - call = getCall(id); - if (call == NULL) - return -1; - call->setStatus(string(HUNGUP_STATUS)); - call->setState(Refused); - ringtone(false); - delete call; - return call->refuse(); -} - -int -Manager::saveConfig (void) -{ - return (Config::tree()->saveToFile(_path.data()) ? 1 : 0); -} - -int -Manager::registerVoIPLink (void) -{ - if (_voIPLinkVector->at(DFT_VOIP_LINK)->setRegister() == 0) { - return 1; - } else { - return 0; - } -} - -int -Manager::quitApplication (void) -{ - // Quit VoIP-link library - _voIPLinkVector->at(DFT_VOIP_LINK)->quit(); - if (saveConfig()) { - Config::deleteTree(); - return 1; - } else { - return 0; - } -} - -int -Manager::sendTextMessage (short , const string& ) -{ - return 1; -} - -int -Manager::accessToDirectory (void) -{ - return 1; -} - -int -Manager::sendDtmf (short id, char code) -{ - int sendType = get_config_fields_int(SIGNALISATION, SEND_DTMF_AS); - - switch (sendType) { - // SIP INFO - case 0: - _voIPLinkVector->at(DFT_VOIP_LINK)->carryingDTMFdigits(id, code); - return 1; - break; - - // Audio way - case 1: - return 1; - break; - - // rfc 2833 - case 2: - return 1; - break; - - default: - return -1; - break; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Management of event peer IP-phone -/////////////////////////////////////////////////////////////////////////////// - -int -Manager::incomingCall (short id) -{ - Call* call; - call = getCall(id); - if (call == NULL) - return -1; - call->setType(Incoming); - call->setStatus(string(RINGING_STATUS)); - call->setState(Progressing); - ringtone(true); - displayStatus(RINGING_STATUS); - return _gui->incomingCall(id); -} - -// L'autre personne a repondu -void -Manager::peerAnsweredCall (short id) -{ - Call* call; - - if (getbRingback()) { - ringback(false); - } - call = getCall(id); - call->setStatus(string(CONNECTED_STATUS)); - - call->setState(Answered); - if (isCurrentId(id)) { - _gui->peerAnsweredCall(id); - } -} - -int -Manager::peerRingingCall (short id) -{ - Call* call; - - call = getCall(id); - call->setStatus(string(RINGING_STATUS)); - call->setState(Ringing); - - ringback(true); - _gui->peerRingingCall(id); - displayStatus(RINGING_STATUS); - return 1; -} - -int -Manager::peerHungupCall (short id) -{ - Call* call; - - call = getCall(id); - call->setStatus(string(HUNGUP_STATUS)); - call->setState(Hungup); - _gui->peerHungupCall(id); - if (getbRingback()) { - ringback(false); - } - _mutex.enterMutex(); - _nCalls -= 1; - _mutex.leaveMutex(); - deleteCall(id); - return 1; -} - -void -Manager::displayTextMessage (short id, const string& message) -{ - _gui->displayTextMessage(id, message); -} - -void -Manager::displayErrorText (const string& message) -{ - _gui->displayErrorText(message); -} - -void -Manager::displayError (const string& error) -{ - _gui->displayStatus(error); -} - -void -Manager::displayStatus (const string& status) -{ - _gui->displayStatus(status); -} - -int -Manager::selectedCall (void) -{ - return _gui->selectedCall(); -} - -bool -Manager::isCurrentId (short id) -{ - return _gui->isCurrentId(id); -} - -void -Manager::congestion (bool var) { - if (isDriverLoaded()) { - if (_congestion != var) { - _congestion = var; - } - _zonetone = var; - _tone->toneHandle(ZT_TONE_CONGESTION); - } else { - _error->errorName(OPEN_FAILED_DEVICE); - } -} - -void -Manager::ringback (bool var) { - if (isDriverLoaded()) { - if (_ringback != var) { - _ringback = var; - } - _zonetone = var; - _tone->toneHandle(ZT_TONE_RINGTONE); - } else { - _error->errorName(OPEN_FAILED_DEVICE); - } -} - -void -Manager::ringtone (bool var) -{ - if (isDriverLoaded()) { - if (getNumberOfCalls() > 1 and _zonetone and var == false) { - // If more than one line is ringing - _zonetone = false; - _tone->playRingtone((_gui->getRingtoneFile()).data()); - } - - if (_ringtone != var) { - _ringtone = var; - } - - _zonetone = var; - if (getNumberOfCalls() == 1) { - // If just one line is ringing - _tone->playRingtone((_gui->getRingtoneFile()).data()); - } - } else { - _error->errorName(OPEN_FAILED_DEVICE); - } -} - -void -Manager::notificationIncomingCall (void) { - int16* buf_ctrl_vol; - int16* buffer = new int16[SAMPLING_RATE]; - int size = SAMPLING_RATE/2; - int k, spkrVolume; - - _tone->generateSin(440, 0, buffer); - - // Control volume - buf_ctrl_vol = new int16[size]; - spkrVolume = getSpkrVolume(); - for (int j = 0; j < size; j++) { - k = j*2; - buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j] * spkrVolume/100; - } - - getAudioDriver()->urgentRingBuffer()->Put(buf_ctrl_vol, - size * CHANNELS); - - getAudioDriver()->startStream(); - getAudioDriver()->sleep(NOTIFICATION_LEN); - getAudioDriver()->stopStream(); - - delete[] buffer; - delete[] buf_ctrl_vol; -} - -void -Manager::getStunInfo (StunAddress4& stunSvrAddr) { - StunAddress4 mappedAddr; - struct in_addr in; - char* addr; - char to[16]; - bzero (to, 16); - - int fd3, fd4; - bool ok = stunOpenSocketPair(stunSvrAddr, - &mappedAddr, - &fd3, - &fd4); - if (ok) { - closesocket(fd3); - closesocket(fd4); - _debug("Got port pair at %d\n", mappedAddr.port); - _firewallPort = mappedAddr.port; - - // Convert ipv4 address to host byte ordering - in.s_addr = ntohl (mappedAddr.addr); - addr = inet_ntoa(in); - _firewallAddr = string(addr); - _debug("address firewall = %s\n",_firewallAddr.data()); - } else { - _debug("Opened a stun socket pair FAILED\n"); - } -} - -device_t -Manager::deviceList (int index) -{ - portaudio::AutoSystem autoSys; - portaudio::System &sys = portaudio::System::instance(); - deviceParam.hostApiName = sys.deviceByIndex(index).hostApi().name(); - deviceParam.deviceName = sys.deviceByIndex(index).name(); - return deviceParam; -} - -int -Manager::deviceCount (void) -{ - int numDevices = 0; - - portaudio::AutoSystem autoSys; - portaudio::System &sys = portaudio::System::instance(); - numDevices = sys.deviceCount(); - return numDevices; -} - -bool -Manager::defaultDevice (int index) -{ - bool defaultDisplayed = false; - - portaudio::AutoSystem autoSys; - portaudio::System &sys = portaudio::System::instance(); - if (sys.deviceByIndex(index).isSystemDefaultInputDevice()) { - defaultDisplayed = true; - } - return defaultDisplayed; -} - -bool -Manager::useStun (void) { - if (get_config_fields_int(SIGNALISATION, USE_STUN) == YES) { - return true; - } else { - return false; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Private functions -/////////////////////////////////////////////////////////////////////////////// - -short -Manager::generateNewCallId (void) -{ - short random_id = rand(); - - // Check if already a call with this id exists - while (getCall(random_id) != NULL or random_id <= 0) { - random_id = rand(); - } - _mutex.enterMutex(); - _nCalls += 1; - _mutex.leaveMutex(); - // If random_id is not attributed, returns it. - return random_id; -} - -unsigned int -Manager::callVectorSize (void) -{ - return _callVector->size(); -} - -int -Manager::createSettingsPath (void) { - int exist = 1; - _path = string(HOMEDIR) + "/." + PROGNAME; - - if (mkdir (_path.data(), 0755) != 0) { - // If directory creation failed - if (errno != EEXIST) { - _debug("Cannot create directory: %d\n", strerror(errno)); - return -1; - } - } - - // Load user's config - _path = _path + "/" + PROGNAME + "rc"; - - exist = Config::tree()->populateFromFile(_path); - - if (exist == 0){ - // If populateFromFile failed - return 0; - } else if (exist == 2) { - // If file doesn't exist yet - return 2; - } - return exist; -} - -void -Manager::initConfigFile (void) -{ - fill_config_fields_int(SIGNALISATION, VOIP_LINK_ID, DFT_VOIP_LINK); - fill_config_fields_str(SIGNALISATION, FULL_NAME, EMPTY_FIELD); - fill_config_fields_str(SIGNALISATION, USER_PART, EMPTY_FIELD); - fill_config_fields_str(SIGNALISATION, AUTH_USER_NAME, EMPTY_FIELD); - fill_config_fields_str(SIGNALISATION, PASSWORD, EMPTY_FIELD); - fill_config_fields_str(SIGNALISATION, HOST_PART, EMPTY_FIELD); - fill_config_fields_str(SIGNALISATION, PROXY, EMPTY_FIELD); - fill_config_fields_int(SIGNALISATION, AUTO_REGISTER, YES); - fill_config_fields_int(SIGNALISATION, PLAY_TONES, YES); - fill_config_fields_int(SIGNALISATION, PULSE_LENGTH, DFT_PULSE_LENGTH); - fill_config_fields_int(SIGNALISATION, SEND_DTMF_AS, SIP_INFO); - fill_config_fields_str(SIGNALISATION, STUN_SERVER, DFT_STUN_SERVER); - fill_config_fields_int(SIGNALISATION, USE_STUN, NO); - - fill_config_fields_int(AUDIO, DRIVER_NAME, DFT_DRIVER); - fill_config_fields_int(AUDIO, NB_CODEC, DFT_NB_CODEC); - fill_config_fields_str(AUDIO, CODEC1, DFT_CODEC); - fill_config_fields_str(AUDIO, CODEC2, DFT_CODEC); - fill_config_fields_str(AUDIO, CODEC3, DFT_CODEC); - fill_config_fields_str(AUDIO, CODEC4, DFT_CODEC); - fill_config_fields_str(AUDIO, CODEC5, DFT_CODEC); - fill_config_fields_str(AUDIO, RING_CHOICE, DFT_RINGTONE); - fill_config_fields_int(AUDIO, VOLUME_SPKR_X, DFT_VOL_SPKR_X); - fill_config_fields_int(AUDIO, VOLUME_SPKR_Y, DFT_VOL_SPKR_Y); - fill_config_fields_int(AUDIO, VOLUME_MICRO_X, DFT_VOL_MICRO_X); - fill_config_fields_int(AUDIO, VOLUME_MICRO_Y, DFT_VOL_MICRO_Y); - - fill_config_fields_str(PREFERENCES, SKIN_CHOICE, DFT_SKIN); - fill_config_fields_int(PREFERENCES, CONFIRM_QUIT, YES); - fill_config_fields_str(PREFERENCES, ZONE_TONE, DFT_ZONE); - fill_config_fields_int(PREFERENCES, CHECKED_TRAY, NO); - fill_config_fields_str(PREFERENCES, VOICEMAIL_NUM, DFT_VOICEMAIL); -} - -void -Manager::initAudioCodec (void) -{ - _nCodecs = get_config_fields_int(AUDIO, NB_CODEC); - _codecDescVector = new CodecDescriptorVector(); - - _codecDescVector->push_back(new CodecDescriptor( - get_config_fields_str(AUDIO, CODEC1))); - - _codecDescVector->push_back(new CodecDescriptor( - get_config_fields_str(AUDIO, CODEC2))); - - _codecDescVector->push_back(new CodecDescriptor( - get_config_fields_str(AUDIO, CODEC3))); -} - -void -Manager::selectAudioDriver (void) -{ - -#if defined(AUDIO_PORTAUDIO) - _audiodriverPA = new AudioLayer(this); - _audiodriverPA->openDevice(get_config_fields_int(AUDIO, DRIVER_NAME)); -#else -# error You must define one AUDIO driver to use. -#endif -} - -// EOF diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index af8cc18824..c7c3852a16 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -285,7 +285,7 @@ SipVoIPLink::answer (short id) int SipVoIPLink::hangup (short id) { - int i = 1; + int i = 0; if (!Manager::instance().getbCongestion()) { _debug("Hang up call [id = %d, cid = %d, did = %d]\n", id, getSipCall(id)->getCid(), getSipCall(id)->getDid()); @@ -306,7 +306,7 @@ SipVoIPLink::hangup (short id) int SipVoIPLink::cancel (short id) { - int i = 1; + int i = 0; if (!Manager::instance().getbCongestion()) { _debug("Cancel call [id = %d, cid = %d]\n", id, getCid()); // Release SIP stack. diff --git a/utilspp/lifetime_default.hpp b/utilspp/lifetime_default.hpp new file mode 100644 index 0000000000..b0815c60ae --- /dev/null +++ b/utilspp/lifetime_default.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_DEFAULT_HPP +#define LIFETIME_DEFAULT_HPP + +#include <stdexcept> +#include <cstdlib> + +namespace utilspp +{ + template< typename T > + class lifetime_default + { + public: + static void schedule_destruction( T *obj, void (*func)() ); + static void on_dead_reference(); + }; +}; + +template< typename T > +void +utilspp::lifetime_default< T >::schedule_destruction( T *, void (*func)() ) +{ + std::atexit(func); +} + +template< typename T > +void +utilspp::lifetime_default< T >::on_dead_reference() +{ + throw std::logic_error( "Dead reference detected" ); +} + +#endif + diff --git a/utilspp/lifetime_with_longevity.hpp b/utilspp/lifetime_with_longevity.hpp new file mode 100644 index 0000000000..eb75a87f42 --- /dev/null +++ b/utilspp/lifetime_with_longevity.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_WITH_LONGEVITY_HPP +#define LIFETIME_WITH_LONGEVITY_HPP + +#include <cassert> + +#include "private_members.hpp" + +namespace utilspp +{ + + template< typename T > + unsigned int get_longevity( T *p ); + + /** + * Assigns an object a longevity. Ensures ordered destructions of objects + * registered thusly during the exit sequence of the application. + */ + template< typename T, typename T_destroyer > + void set_longevity( + T *obj, + unsigned int longevity, + T_destroyer d = utilspp::private_members::deleter< T >::delete_object + ); + + template< typename T > + struct lifetime_with_longevity + { + static void schedule_destruction( T *obj, void (*func)() ); + static void on_dead_reference(); + }; +}; + +#include "lifetime_with_longevity.inl" + +#endif + diff --git a/utilspp/lifetime_with_longevity.inl b/utilspp/lifetime_with_longevity.inl new file mode 100644 index 0000000000..66e7817255 --- /dev/null +++ b/utilspp/lifetime_with_longevity.inl @@ -0,0 +1,67 @@ +template< typename T, typename T_destroyer > +void +utilspp::set_longevity( T *obj, unsigned int longevity, T_destroyer d ) +{ + using namespace utilspp::private_members; + + tracker_array new_array = static_cast< tracker_array >( + std::realloc( + m_tracker_array, + m_nb_elements + 1 + ) + ); + if( new_array == NULL ) + { + throw std::bad_alloc(); + } + + lifetime_tracker *p = new concrete_lifetime_tracker< T, T_destroyer >( + obj, + longevity, + d + ); + + m_tracker_array = new_array; + + tracker_array pos = std::upper_bound( + m_tracker_array, + m_tracker_array + m_nb_elements, + p, + &lifetime_tracker::compare + ); + std::copy_backward( + pos, + m_tracker_array + m_nb_elements, + m_tracker_array + m_nb_elements + 1 + ); + + *pos = p; + m_nb_elements++; + std::atexit( &at_exit_func ); +}; + +template< typename T > +void +utilspp::lifetime_with_longevity< T >::schedule_destruction( T *obj, void (*func)() ) +{ + utilspp::private_members::adapter<T> adapter = { func }; + utilspp::set_longevity( obj, get_longevity( obj ), adapter ); +} + +template< typename T > +void +utilspp::lifetime_with_longevity< T >::on_dead_reference() +{ + throw std::logic_error("Dead reference detected"); +} + +template< typename T > +unsigned int +utilspp::get_longevity( T * ) +{ + return 1000; +} + + + + diff --git a/utilspp/null_type.hpp b/utilspp/null_type.hpp new file mode 100644 index 0000000000..f294ef2426 --- /dev/null +++ b/utilspp/null_type.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef NULL_TYPE_HPP +#define NULL_TYPE_HPP + +namespace utilspp +{ + class null_type; +}; + +#endif + diff --git a/utilspp/private_members.hpp b/utilspp/private_members.hpp new file mode 100644 index 0000000000..192f090145 --- /dev/null +++ b/utilspp/private_members.hpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PRIVATE_MEMBERS_HPP +#define PRIVATE_MEMBERS_HPP + +#include <cassert> + +namespace utilspp +{ + namespace private_members + { + /** + * Helper class for utils::set_longevity + */ + class lifetime_tracker + { + public: + lifetime_tracker( unsigned int longevity ); + virtual ~lifetime_tracker(); + static bool compare( + const lifetime_tracker *l, + const lifetime_tracker *r + ); + + private: + unsigned int m_longevity; + }; + + typedef lifetime_tracker** tracker_array; + + extern tracker_array m_tracker_array; + extern int m_nb_elements; + + /** + * Helper class for Destroyer + */ + template< typename T > + struct deleter + { + void delete_object( T *obj ); + }; + + /** + * Concrete lifetime tracker for objects of type T + */ + template< typename T, typename T_destroyer > + class concrete_lifetime_tracker : public lifetime_tracker + { + public: + concrete_lifetime_tracker( + T *obj, + unsigned int longevity, + T_destroyer d + ); + + ~concrete_lifetime_tracker(); + + private: + T* m_tracked; + T_destroyer m_destroyer; + }; + + void at_exit_func(); + + template <class T> + struct adapter + { + void operator()(T*); + void (*m_func)(); + }; + }; +}; + +#include "private_members.inl" + +#endif + diff --git a/utilspp/private_members.inl b/utilspp/private_members.inl new file mode 100644 index 0000000000..d4c4539180 --- /dev/null +++ b/utilspp/private_members.inl @@ -0,0 +1,31 @@ +template< typename T > +void +utilspp::private_members::deleter< T >::delete_object( T *obj ) +{ + delete obj; +} + +template< typename T, typename T_destroyer > +utilspp::private_members::concrete_lifetime_tracker< T, T_destroyer >::concrete_lifetime_tracker( + T *obj, + unsigned int longevity, + T_destroyer d + ) +: lifetime_tracker( longevity ) +, m_tracked( obj ) +, m_destroyer( d ) +{} + +template< typename T, typename T_destroyer > +utilspp::private_members::concrete_lifetime_tracker< T, T_destroyer >::~concrete_lifetime_tracker() +{ + m_destroyer( m_tracked ); +} + + +template < typename T > +void +utilspp::private_members::adapter< T >::operator()(T*) +{ + return (*m_func)(); +} diff --git a/utilspp/singleton_holder.inl~ b/utilspp/singleton_holder.inl~ deleted file mode 100644 index 06d4a6460a..0000000000 --- a/utilspp/singleton_holder.inl~ +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (cURLpp), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef SINGLETON_HOLDER_INL -#define SINGLETON_HOLDER_INL - -template -< -class T, -template < class > class T_creation_policy, -template < class > class T_lifetime_policy, -template < class > class T_threading_model -> -T& -utilspp::singleton_holder -< -T, -T_creation_policy, -T_lifetime_policy, -T_threading_model -> -::instance() -{ - if ( m_instance == NULL ) - { - make_instance(); - } - - return ( *m_instance ); -}; - -template -< -class T, -template < class > class T_creation_policy, -template < class > class T_lifetime_policy, -template < class > class T_threading_model -> -void -utilspp::singleton_holder -< -T, -T_creation_policy, -T_lifetime_policy, -T_threading_model ->::make_instance() -{ - typename T_threading_model< T >::lock guard; -(void)guard; - - if ( m_instance == NULL ) - { - if ( m_destroyed ) - { - T_lifetime_policy< T >::on_dead_reference(); - m_destroyed = false; - } - - m_instance = T_creation_policy< T >::create(); - T_lifetime_policy< T >::schedule_destruction( m_instance, &destroy_singleton ); - } -} - -template -< -class T, -template < class > class T_creation_policy, -template < class > class T_lifetime_policy, -template < class > class T_threading_model -> -void -utilspp::singleton_holder -< -T, -T_creation_policy, -T_lifetime_policy, -T_threading_model -> -::destroy_singleton() -{ - assert( !m_destroyed ); - T_creation_policy< T >::destroy( m_instance ); - m_instance = NULL; - m_destroyed = true; -} - -template < class T, -template < class > class C, -template < class > class L, -template < class > class M -> -typename utilspp::singleton_holder< T, C, L, M>::instance_type -utilspp::singleton_holder< T, C, L, M >::m_instance; - -template -< -class T, -template < class > class C, -template < class > class L, -template < class > class M -> -bool utilspp::singleton_holder< T, C, L, M >::m_destroyed; - -#endif diff --git a/utilspp/threading_single.hpp b/utilspp/threading_single.hpp new file mode 100644 index 0000000000..1923bd1b8d --- /dev/null +++ b/utilspp/threading_single.hpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLE_THREADED_HPP +#define SINGLE_THREADED_HPP + +#include "null_type.hpp" + +namespace utilspp +{ + template < typename T = utilspp::null_type > + struct threading_single + { + struct mutex + { + void lock(); + void unlock(); + }; + + struct lock + { + lock(); + lock( mutex &m ); + }; + + typedef T volatile_type; + }; +}; + +template< typename T > +inline +utilspp::threading_single< T >::lock::lock() +{}; + +template< typename T > +inline +utilspp::threading_single< T >::lock::lock( + utilspp::threading_single< T >::mutex & ) +{} + +template< typename T > +inline +void +utilspp::threading_single< T >::mutex::lock() +{}; + +template< typename T > +inline +void +utilspp::threading_single< T >::mutex::unlock() +{}; + +#endif + -- GitLab