From e45e859e870aec1e129c035cf51095a6079e41d9 Mon Sep 17 00:00:00 2001 From: yanmorin <yanmorin> Date: Tue, 4 Oct 2005 19:39:43 +0000 Subject: [PATCH] Remove the old config Add mutex to audiolayer (its share between 3 or 4 threads) Add mutex to the tone (its share by two threads) Simplify the tone interface... Remove the qtGUImainwindow from the compilation with the ENABLE_MAINTENER --- src/audio/audiolayer.cpp | 20 +++ src/audio/audiolayer.h | 5 + src/audio/audiortp.cpp | 64 ++++---- src/audio/ringbuffer.cpp | 24 +-- src/audio/ringbuffer.h | 3 - src/audio/tonegenerator.cpp | 121 ++++++++------- src/audio/tonegenerator.h | 32 ++-- src/configitem.cpp | 130 ---------------- src/configitem.h | 57 ------- src/configuration.cpp | 115 -------------- src/configuration.h | 53 ------- src/configurationtree.cpp | 190 ----------------------- src/configurationtree.h | 59 -------- src/gui/Makefile.am | 12 +- src/gui/guiframework.h | 1 - src/gui/qt/point.cpp | 2 + src/gui/qt/qtGUImainwindow.cpp | 12 +- src/gui/server/guiserverimpl.cpp | 6 - src/gui/server/guiserverimpl.h | 1 - src/gui/server/request.cpp | 2 +- src/gui/server/requestconfig.cpp | 3 +- src/gui/server/tcpsessionio.cpp | 29 ++-- src/gui/server/tcpsessionio.h | 29 ++-- src/managerimpl.cpp | 252 ++++++++++++++----------------- src/managerimpl.h | 41 +++-- src/sipcall.cpp | 147 +++++++++--------- src/sipcall.h | 5 + src/sipvoiplink.cpp | 197 ++++++++++++------------ src/user_cfg.h | 2 - 29 files changed, 524 insertions(+), 1090 deletions(-) delete mode 100644 src/configitem.cpp delete mode 100644 src/configitem.h delete mode 100644 src/configuration.cpp delete mode 100644 src/configuration.h delete mode 100644 src/configurationtree.cpp delete mode 100644 src/configurationtree.h diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp index c6642ddeea..6e5b6ce506 100644 --- a/src/audio/audiolayer.cpp +++ b/src/audio/audiolayer.cpp @@ -42,12 +42,14 @@ AudioLayer::AudioLayer () // Destructor AudioLayer::~AudioLayer (void) { + portaudio::System::terminate(); closeStream(); } void AudioLayer::closeStream (void) { + ost::MutexLock guard(_mutex); if(_stream) { _stream->close(); delete _stream; @@ -57,6 +59,7 @@ AudioLayer::closeStream (void) void AudioLayer::openDevice (int index) { + ost::MutexLock guard(_mutex); closeStream(); // Set up the parameters required to open a (Callback)Stream: portaudio::DirectionSpecificStreamParameters @@ -83,6 +86,7 @@ AudioLayer::openDevice (int index) void AudioLayer::startStream(void) { + ost::MutexLock guard(_mutex); if (Manager::instance().isDriverLoaded()) { if (_stream && !_stream->isActive()) { _stream->start(); @@ -93,6 +97,7 @@ AudioLayer::startStream(void) void AudioLayer::stopStream(void) { + ost::MutexLock guard(_mutex); if (Manager::instance().isDriverLoaded()) { if (_stream && !_stream->isStopped()) { _stream->stop(); @@ -109,6 +114,7 @@ AudioLayer::sleep(int msec) bool AudioLayer::isStreamActive (void) { + ost::MutexLock guard(_mutex); if(_stream && _stream->isActive()) { return true; } @@ -117,9 +123,22 @@ AudioLayer::isStreamActive (void) } } +void +AudioLayer::putMain(void* buffer, int toCopy) +{ + ost::MutexLock guard(_mutex); + _mainSndRingBuffer.Put(buffer, toCopy); +} +void +AudioLayer::putUrgent(void* buffer, int toCopy) +{ + ost::MutexLock guard(_mutex); + _urgentRingBuffer.Put(buffer, toCopy); +} bool AudioLayer::isStreamStopped (void) { + ost::MutexLock guard(_mutex); if(_stream && _stream->isStopped()) { return true; } @@ -159,6 +178,7 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer, normalAvail = _mainSndRingBuffer.AvailForGet(); toGet = (normalAvail < (int)framesPerBuffer) ? normalAvail : framesPerBuffer; + //_debug("%d vs %d : %d\t", normalAvail, (int)framesPerBuffer, toGet); _mainSndRingBuffer.Get(out, SAMPLES_SIZE(toGet)); } diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h index 165e455fa8..93ff22563a 100644 --- a/src/audio/audiolayer.h +++ b/src/audio/audiolayer.h @@ -27,6 +27,7 @@ #include "../global.h" #include "ringbuffer.h" +#include <cc++/thread.h> #define FRAME_PER_BUFFER 160 #define MIC_CHANNELS 2 // 1=mono 2=stereo @@ -49,6 +50,9 @@ public: bool isStreamActive (void); bool isStreamStopped (void); + void putMain(void* buffer, int toCopy); + void putUrgent(void* buffer, int toCopy); + int audioCallback (const void *, void *, unsigned long, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags); @@ -64,6 +68,7 @@ private: portaudio::MemFunCallbackStream<AudioLayer> *_stream; portaudio::AutoSystem autoSys; + ost::Mutex _mutex; }; #endif // _AUDIO_LAYER_H_ diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index 2491972521..41176ac3df 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -91,6 +91,7 @@ AudioRtp::closeRtpSession (SipCall *ca) { // Stop portaudio and flush ringbuffer Manager::instance().getAudioDriver()->stopStream(); Manager::instance().getAudioDriver()->mainSndRingBuffer().flush(); + _debug("AudioRtp::closeRtpSession : flushing stream\n"); } } @@ -102,11 +103,11 @@ AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, bool sym) { time = new Time(); _ca = sipcall; - _sym =sym; + _sym = sym; _audioDevice = driver; // TODO: Change bind address according to user settings. - std::string localipConfig = Manager::instance().getConfigString(SIGNALISATION,LOCAL_IP); + std::string localipConfig = _ca->getLocalIp(); InetHostAddress local_ip(localipConfig.c_str()); _debug("RTP: listening on IP %s local port : %d\n", localipConfig.c_str(), _ca->getLocalAudioPort()); @@ -119,21 +120,16 @@ AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, } AudioRtpRTX::~AudioRtpRTX () { - if (!_sym) { - if (_sessionRecv != NULL) { - delete _sessionRecv; - _sessionRecv = NULL; - } - if (_sessionSend != NULL) { - delete _sessionSend; - _sessionSend = NULL; - } - } else { - if (_session != NULL) { - delete _session; - _session = NULL; - } - } + if (!_sym) { + delete _sessionRecv; + _sessionRecv = NULL; + delete _sessionSend; + _sessionSend = NULL; + } else { + delete _session; + _session = NULL; + } + delete time; } void @@ -143,7 +139,7 @@ AudioRtpRTX::initAudioRtpSession (void) if (!remote_ip) { _debug("RTP: Target IP address [%s] is not correct!\n", _ca->getRemoteSdpAudioIp()); - exit(); + return; } else { _debug("RTP: Sending to %s : %d\n", _ca->getRemoteSdpAudioIp(), _ca->getRemoteSdpAudioPort()); } @@ -165,7 +161,7 @@ AudioRtpRTX::initAudioRtpSession (void) (unsigned short) _ca->getRemoteSdpAudioPort())) { _debug("RTX send: could not connect to port %d\n", _ca->getRemoteSdpAudioPort()); - exit(); + return; } else { _debug("RTP(Send): Added destination %s : %d\n", remote_ip.getHostname(), @@ -182,7 +178,7 @@ AudioRtpRTX::initAudioRtpSession (void) } else { if (!_session->addDestination (remote_ip, (unsigned short) _ca->getRemoteSdpAudioPort())) { - exit(); + return; } else { _session->setPayloadFormat(StaticPayloadFormat((StaticPayloadType) _ca->payload)); setCancel(cancelImmediate); @@ -284,7 +280,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers, // If the current call is the call which is answered //if (Manager::instance().isCurrentId(_ca->getId())) { // Set decoded data to sound device - Manager::instance().getAudioDriver()->mainSndRingBuffer().Put(data_for_speakers_tmp, SAMPLES_SIZE(RTP_FRAMES2SEND)); + Manager::instance().getAudioDriver()->putMain(data_for_speakers_tmp, SAMPLES_SIZE(RTP_FRAMES2SEND)); //} // Notify (with a beep) an incoming call when there is already a call @@ -299,7 +295,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers, Manager::instance().getAudioDriver()->startStream(); - + delete ac; delete cd; delete adu; } @@ -332,7 +328,8 @@ AudioRtpRTX::run (void) { TimerPort::setTimer(frameSize); // flush stream: - AudioLayer *audiolayer = Manager::instance().getAudioDriver(); + ManagerImpl& manager = Manager::instance(); + AudioLayer *audiolayer = manager.getAudioDriver(); audiolayer->mainSndRingBuffer().flush(); audiolayer->urgentRingBuffer().flush(); @@ -344,11 +341,9 @@ AudioRtpRTX::run (void) { _session->startRunning(); } - - - while (_ca->enable_audio != -1) { - micVolume = Manager::instance().getMicroVolume(); - spkrVolume = Manager::instance().getSpkrVolume(); + while (!testCancel() && _ca->enable_audio != -1) { + micVolume = manager.getMicroVolume(); + spkrVolume = manager.getSpkrVolume(); //////////////////////////// // Send session @@ -369,16 +364,15 @@ AudioRtpRTX::run (void) { TimerPort::incTimer(frameSize); // 'frameSize' ms } + delete[] data_for_speakers_tmp; + delete[] data_for_speakers; + delete[] data_to_send; + delete[] data_from_mic_tmp; + delete[] data_from_mic; + audiolayer->mainSndRingBuffer().flush(); //audiolayer->urgentRingBuffer().flush(); audiolayer->stopStream(); - - delete[] data_for_speakers; - delete[] data_for_speakers_tmp; - delete[] data_from_mic; - delete[] data_from_mic_tmp; - delete[] data_to_send; - exit(); } diff --git a/src/audio/ringbuffer.cpp b/src/audio/ringbuffer.cpp index ba810eed0a..5a6a74824d 100644 --- a/src/audio/ringbuffer.cpp +++ b/src/audio/ringbuffer.cpp @@ -45,25 +45,13 @@ RingBuffer::RingBuffer(int size) { RingBuffer::~RingBuffer() { free (mBuffer); } - -void -RingBuffer::lock (void) -{ - mMutex.enterMutex(); -} - -void -RingBuffer::unlock (void) -{ - mMutex.leaveMutex(); -} void RingBuffer::flush (void) { - lock(); + mMutex.enterMutex(); mStart = 0; mEnd = 0; - unlock(); + mMutex.leaveMutex(); } int @@ -88,7 +76,7 @@ RingBuffer::Put(void* buffer, int toCopy) { int pos; int len = Len(); - lock(); + mMutex.enterMutex(); if (toCopy > (mBufferSize-4) - len) toCopy = (mBufferSize-4) - len; @@ -113,7 +101,7 @@ RingBuffer::Put(void* buffer, int toCopy) { mEnd = pos; - unlock(); + mMutex.leaveMutex(); // How many items copied. return copied; @@ -137,7 +125,7 @@ RingBuffer::Get(void *buffer, int toCopy) { int copied; int len = Len(); - lock(); + mMutex.enterMutex(); if (toCopy > len) toCopy = len; @@ -156,7 +144,7 @@ RingBuffer::Get(void *buffer, int toCopy) { copied += block; } - unlock(); + mMutex.leaveMutex(); return copied; } diff --git a/src/audio/ringbuffer.h b/src/audio/ringbuffer.h index 0d79730d74..63bdf7c669 100644 --- a/src/audio/ringbuffer.h +++ b/src/audio/ringbuffer.h @@ -56,9 +56,6 @@ class RingBuffer { private: // T getNextSample(void); - void lock (void); - void unlock (void); - ost::Mutex mMutex; int mStart; int mEnd; diff --git a/src/audio/tonegenerator.cpp b/src/audio/tonegenerator.cpp index 4bb4bc4f04..2191c69098 100644 --- a/src/audio/tonegenerator.cpp +++ b/src/audio/tonegenerator.cpp @@ -25,7 +25,6 @@ #include "audiolayer.h" #include "codecDescriptor.h" #include "ringbuffer.h" -#include "ulaw.h" #include "tonegenerator.h" #include "../global.h" #include "../manager.h" @@ -40,8 +39,9 @@ int AMPLITUDE = 8192; // ToneThread implementation /////////////////////////////////////////////////////////////////////////////// ToneThread::ToneThread (int16 *buf, int size) : Thread () { - this->buffer = buf; + this->buffer = buf; this->size = size; + // channels is 2 (global.h) this->buf_ctrl_vol = new int16[size*CHANNELS]; } @@ -59,23 +59,23 @@ ToneThread::run (void) { // unsigned int play_time = (size * 1000) / SAMPLING_RATE; unsigned int pause = (size) / SAMPLING_RATE; - while (Manager::instance().getZonetone()) { - + ManagerImpl& manager = Manager::instance(); + while (!testCancel()) { + // Create a new stereo buffer with the volume adjusted - spkrVolume = Manager::instance().getSpkrVolume(); + spkrVolume = manager.getSpkrVolume(); for (int j = 0; j < size; j++) { - k = j*2; + k = j*2; // channels is 2 (global.h) 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)); + manager.getAudioDriver()->putMain(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(); + manager.getAudioDriver()->startStream(); } // next iteration later, sound is playing. @@ -90,10 +90,19 @@ ToneThread::run (void) { ToneGenerator::ToneGenerator () { this->initTone(); tonethread = NULL; + _dst = NULL; + _src = NULL; + _ulaw = new Ulaw (PAYLOAD_CODEC_ULAW, "G711u"); + + _currentTone = ZT_TONE_NULL; + _currentZone = 0; } ToneGenerator::~ToneGenerator (void) { delete tonethread; + delete [] _dst; + delete [] _src; + delete _ulaw; } /** @@ -103,7 +112,7 @@ void ToneGenerator::initTone (void) { toneZone[ID_NORTH_AMERICA][ZT_TONE_DIALTONE] = "350+440"; toneZone[ID_NORTH_AMERICA][ZT_TONE_BUSY] = "480+620/500,0/500"; - toneZone[ID_NORTH_AMERICA][ZT_TONE_RINGTONE] = "440+480/2000,0/4000"; + toneZone[ID_NORTH_AMERICA][ZT_TONE_RINGTONE] = "440+480/2000,0/2000"; toneZone[ID_NORTH_AMERICA][ZT_TONE_CONGESTION] = "480+620/250,0/250"; toneZone[ID_FRANCE][ZT_TONE_DIALTONE] = "440"; @@ -149,7 +158,7 @@ ToneGenerator::initTone (void) { * @param ptr for result buffer */ void -ToneGenerator::generateSin (int lowerfreq, int higherfreq, int16* ptr) { +ToneGenerator::generateSin (int lowerfreq, int higherfreq, int16* ptr) const { double var1, var2; var1 = (double)2 * (double)M_PI * (double)higherfreq / (double)SAMPLING_RATE; @@ -170,11 +179,11 @@ ToneGenerator::generateSin (int lowerfreq, int higherfreq, int16* ptr) { * @param ns section number of format tone */ void -ToneGenerator::buildTone (int idCountry, int idTones, int16* temp) { +ToneGenerator::buildTone (unsigned int idCountry, unsigned int idTones, int16* temp) { string s; int count = 0; int byte = 0, - byte_temp = 0; + byte_temp = 0; static int nbcomma = 0; int16 *buffer = new int16[SIZEBUF]; //1kb int pos; @@ -283,38 +292,51 @@ ToneGenerator::idZoneName (const string& name) { * @param var: indicates begin/end of the tone */ void -ToneGenerator::toneHandle (int idr) { - std::string zone = Manager::instance().getConfigString(PREFERENCES, -ZONE_TONE); - int idz = idZoneName(zone); - - if (idz != -1) { - buildTone (idz, idr, buf); +ToneGenerator::toneHandle (unsigned int idr, const std::string& zone) { + if (idr == ZT_TONE_NULL) return; + unsigned int idz = idZoneName(zone); + // if the tonethread run + if ( tonethread != NULL ) { + // if it's the good tone and good zone, do nothing + if (idr == _currentTone && idz == _currentZone ) { + // do nothing + return; + } else { + + stopTone(); + _currentTone = idr; + _currentZone = idz; + } + } else { + _currentTone = idr; + _currentZone = idz; + } + buildTone(idz, idr, buf); + tonethread = new ToneThread(buf, totalbytes); + tonethread->start(); +} - // New thread for the tone - if (tonethread == NULL) { - tonethread = new ToneThread (buf, totalbytes); - tonethread->start(); - } +void +ToneGenerator::stopTone() { + _currentTone = ZT_TONE_NULL; - if (!Manager::instance().getZonetone()) { - Manager::instance().getAudioDriver()->stopStream(); - Manager::instance().getAudioDriver()->mainSndRingBuffer().flush(); - if (tonethread != NULL) { - delete tonethread; - tonethread = NULL; - } - } - } -} + // we end the last thread + delete tonethread; + tonethread = NULL; + // we flush the main buffer (with blank) + Manager::instance().getAudioDriver()->mainSndRingBuffer().flush(); +} int ToneGenerator::playRingtone (const char *fileName) { - short* dst = NULL; - char* src = NULL; + if (tonethread != NULL) { + stopTone(); + } + delete [] _dst; + delete [] _src; + int expandedsize, length; - Ulaw* ulaw = new Ulaw (PAYLOAD_CODEC_ULAW, "G711u"); if (fileName == NULL) { return 0; @@ -332,30 +354,19 @@ ToneGenerator::playRingtone (const char *fileName) { file.seekg (0, ios::beg); // allocate memory: - src = new char [length]; - dst = new short[length*2]; + _src = new char [length]; + _dst = new short[length*2]; - // read data as a block: - file.read (src,length); + // read data as a block: + file.read (_src,length); // Decode file.ul - expandedsize = ulaw->codecDecode (dst, (unsigned char *)src, length); + expandedsize = _ulaw->codecDecode (_dst, (unsigned char *)_src, length); if (tonethread == NULL) { - tonethread = new ToneThread ((int16*)dst, expandedsize); + tonethread = new ToneThread ((int16*)_dst, expandedsize); tonethread->start(); } - if (!Manager::instance().getZonetone()) { - Manager::instance().getAudioDriver()->stopStream(); - Manager::instance().getAudioDriver()->mainSndRingBuffer().flush(); - if (tonethread != NULL) { - delete tonethread; - tonethread = NULL; - delete[] dst; - delete[] src; - delete ulaw; - } - } file.close(); return 1; diff --git a/src/audio/tonegenerator.h b/src/audio/tonegenerator.h index 8edf1c4922..22c687a31f 100644 --- a/src/audio/tonegenerator.h +++ b/src/audio/tonegenerator.h @@ -23,12 +23,14 @@ #include <string> #include "../global.h" -#include "../manager.h" +#include "ulaw.h" +#include <cc++/thread.h> -#define ZT_TONE_DIALTONE 0 -#define ZT_TONE_BUSY 1 -#define ZT_TONE_RINGTONE 2 -#define ZT_TONE_CONGESTION 3 +#define ZT_TONE_NULL 99 +#define ZT_TONE_DIALTONE 0 +#define ZT_TONE_BUSY 1 +#define ZT_TONE_RINGTONE 2 +#define ZT_TONE_CONGESTION 3 #define NB_TONES_MAX 4 #define NB_ZONES_MAX 7 @@ -73,18 +75,24 @@ public: /** * Calculate sinus with superposition of 2 frequencies */ - void generateSin (int, int, int16 *); + void generateSin (int, int, int16 *) const; /** * Build tone according to the id-zone, with initialisation of ring tone. * Generate sinus with frequencies alternatively by time */ - void buildTone (int, int, int16*); + void buildTone (unsigned int, unsigned int, int16*); /** * Handle the required tone */ - void toneHandle (int); + void toneHandle (unsigned int, const std::string& zone); + + /** + * Stop tone + */ + void stopTone(); + /** * Play the ringtone when incoming call occured @@ -121,7 +129,13 @@ private: ////////////////////////// std::string toneZone[NB_ZONES_MAX][NB_TONES_MAX]; ToneThread* tonethread; - + + short* _dst; + char* _src; + Ulaw* _ulaw; + + unsigned int _currentTone; + unsigned int _currentZone; }; #endif // __TONE_GENRATOR_H__ diff --git a/src/configitem.cpp b/src/configitem.cpp deleted file mode 100644 index b708b058a1..0000000000 --- a/src/configitem.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Copyright (C) 2004-2005 Savoir-Faire Linux inc. - * Author: Jerome Oufella <jerome.oufella@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 <assert.h> -#include <stdio.h> -#include <string.h> - -#include "configitem.h" - -using namespace std; - -ConfigItem::ConfigItem (void) { - init(); -} - -// Create a new ConfigItem, with key name keyName -ConfigItem::ConfigItem (const string& keyName) { - init(); - this->_key = new string(keyName); -} - -// Create a new ConfigItem, with key name keyName and value keyVal. -ConfigItem::ConfigItem (const string& keyName, const string& keyVal) { - init(); - this->_key = new string(keyName); - this->_value = new string(keyVal); -} - -ConfigItem::~ConfigItem (void) { - if (this->_key != NULL) delete this->_key; - if (this->_value != NULL) delete this->_value; -} - - -// Get the value of the passed key -string* -ConfigItem::getValueByKey (const string& keyName) { - assert (_key != NULL); - - if (*_key == keyName) { - return _value; - } else if (_next) { - return _next->getValueByKey(keyName); - } - - return NULL; -} - -// Get item pointer using a key value. -// If key value not found, new item is appended to list. -ConfigItem* -ConfigItem::getItemByKey (const string& keyName) { - assert (_key != NULL); - - if (*_key == keyName) { - return this; - } else if (_next) { - return _next->getItemByKey(keyName); - } - - // Create new ConfigItem in list if non-existent - _next = new ConfigItem(keyName); - return _next; -} - -// This saves a section/item list to fd -void -ConfigItem::saveToFile (fstream *fd) { - if (fd == NULL) return; - - // If we're a section, save our contents first. - if (_head != NULL) { - if (_key != NULL) { - *fd << "[" << _key->data() << "]\n"; - } - _head->saveToFile (fd); - *fd << "\n"; - } - - // Save the items list to file. - if (_next != NULL) { - _next->saveToFile(fd); - } - - // Must save key=value only if not a section. - if (_head == NULL) { - *fd << _key->data() << "=" <<_value->data() << "\n"; - } -} - -// Set the current objects value -void -ConfigItem::setValue (const string& newValue) { - if (_value != NULL) { - delete _value; - } - - _value = new string(newValue); -} - -// Set a value given its key name -void -ConfigItem::setValueByKey (const string& key, const string& value) { - getItemByKey(key)->setValue(value); -} - -// Set the default values -void -ConfigItem::init (void) { - this->_key = NULL; - this->_value = NULL; - this->_next = NULL; - this->_head = NULL; -} - - -// EOF diff --git a/src/configitem.h b/src/configitem.h deleted file mode 100644 index a04d6e9e57..0000000000 --- a/src/configitem.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2004-2005 Savoir-Faire Linux inc. - * Author: Jerome Oufella <jerome.oufella@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. - */ - -#ifndef __CONFIG_ITEM_H__ -#define __CONFIG_ITEM_H__ - -#include <iostream> -#include <fstream> - -#include <string> -#include <stdio.h> - -using namespace std; - -class ConfigItem { -public: - ConfigItem (void); - ConfigItem (const string& ); - ConfigItem (const string& , const string& ); - ~ConfigItem (void); - string* key (void) { return _key; } - string* value (void) { return _value; } - ConfigItem* head (void) { return _head; } - void setHead (ConfigItem *h) { _head = h; } - string* getValueByKey (const string& ); - ConfigItem* getItemByKey (const string& ); - void setValue (const string& ); - void setValueByKey (const string& , const string& ); - void saveToFile (fstream*); - -private: - string* _key; - string* _value; - ConfigItem* _next; - ConfigItem* _head; - void init (void); -}; - -typedef ConfigItem ConfigSection; - -#endif - - - diff --git a/src/configuration.cpp b/src/configuration.cpp deleted file mode 100644 index c655253fe5..0000000000 --- a/src/configuration.cpp +++ /dev/null @@ -1,115 +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 <string> - -#include "configuration.h" -#include "configurationtree.h" - -using namespace std; - -static ConfigurationTree *globalConfigTree = NULL; - - -string -Config::gets (const string& section, const string& key) { - return Config::get (section, key, string("")); -} - - -string -Config::get (const string& section, const string& key, const string& defval) { - string value = tree()->getValue (section, key); - if (value.empty()) { - tree()->setValue(section, key, defval); - return defval; - } else { - return value; - } -} - -string -Config::getchar (const string& section, const string& key, const string& defval){ - string value = tree()->getValue (section, key); - if (value == string("")) { - tree()->setValue(section, key, defval); - return defval; - } else { - return value; - } -} - -int -Config::geti (const string& section, const string& key) { - return Config::get (section, key, 0); -} - -int -Config::get (const string& section, const string& key, int defval) { - string value = tree()->getValue(section, key); - if (value == string("")) { - tree()->setValue(section, key, defval); - return defval; - } else { - return atoi(value.data()); - } -} - -string -Config::set (const string& section, const string& key, const string& val) { - tree()->setValue(section, key, val); - return val; -} - -string -Config::setchar (const string& section, const string& key, const string& val) { - tree()->setValue(section, key, val); - return val; -} - -int -Config::set (const string& section, const string& key, int val) { - tree()->setValue(section, key, val); - return val; -} - -bool -Config::set (const string& section, const string& key, bool val) { - tree()->setValue(section, key, (int)val); - return val; -} - - -void -Config::setTree (ConfigurationTree *t) { - globalConfigTree = t; -} - -void -Config::deleteTree (void) { - delete globalConfigTree; -} - -ConfigurationTree* -Config::tree(void) { - return globalConfigTree; -} - - -// EOF diff --git a/src/configuration.h b/src/configuration.h deleted file mode 100644 index a68365738f..0000000000 --- a/src/configuration.h +++ /dev/null @@ -1,53 +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. - */ - -#ifndef __CONFIG_H__ -#define __CONFIG_H__ - -#include <string> - -#include "global.h" - -using namespace std; - -class ConfigurationTree; -class Config { -public: - Config (void) {}; - ~Config (void) {}; - - static string gets (const string&, const string&); - static int geti (const string&, const string&); - - static string get (const string&, const string&, const string&); - static string getchar (const string&, const string&, const string&); - static int get (const string&, const string&, int); - static bool get (const string&, const string&, bool); - - static int set (const string&, const string&, int); - static bool set (const string&, const string&, bool); - static string set (const string&, const string&, const string&); - static string setchar (const string&, const string&, const string&); - - static void setTree (ConfigurationTree *); - static void deleteTree (void); - static ConfigurationTree* tree (void); -}; - -#endif // __CONFIG_H__ diff --git a/src/configurationtree.cpp b/src/configurationtree.cpp deleted file mode 100644 index ce0bf8ff52..0000000000 --- a/src/configurationtree.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Copyright (C) 2004-2005 Savoir-Faire Linux inc. - * Author: Jerome Oufella <jerome.oufella@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 <iostream> -#include <string> - -#include "global.h" -#include "configitem.h" -#include "configurationtree.h" - -using namespace std; - -// Default constructor -ConfigurationTree::ConfigurationTree (void) { - this->_head = NULL; -} - -// Construct with file name, and load from this file -ConfigurationTree::ConfigurationTree (const string& fileName) { - populateFromFile (fileName); -} - -// Destructor -ConfigurationTree::~ConfigurationTree (void) { - if (_head != NULL) { - delete _head; - } -} - -// Create the tree from an existing ini file -int -ConfigurationTree::populateFromFile (const string& fileName) { - bool out = false; - if (fileName.empty()) { - return 0; - } - - fstream file; - file.open(fileName.data(), fstream::in); - - if (!file.is_open()) { - file.open(fileName.data(), fstream::out); - out = true; - if (!file.is_open()) { - _debug("(%s:%d) Error opening file: %s\n", __FILE__, __LINE__, - fileName.c_str()); - return 0; - } - file.close(); - return 2; - } - - char line[128]; - bzero (line, 128); - - string section(""); - string key(""); - string val(""); - string s; - int pos; - - while (!file.eof()) { - // Read the file line by line - file.getline (line, 128 - 1); - string str(line); - if (str[0] == '[') { - // If the line is a section - pos = str.find(']'); - section = str.substr(1, pos - 1); - } else if (!str.empty() and str[0] != '#') { - // If the line is "key=value" and doesn't begin with '#'(comments) - pos = str.find('='); - key = str.substr(0, pos); - val = str.substr(pos + 1, str.length() - pos); - - if (key.length() > 0 and val.length() > 0) { - setValue(section, key, val); - } - } - } - - file.close(); - return 1; -} - -// Save tree's contents to a file -int -ConfigurationTree::saveToFile (const string& fileName) { - if (fileName.empty() || _head == NULL) { - return 0; - } - - fstream file; - file.open(fileName.data(), fstream::out); - - if (!file.is_open()) { - _debug("(%s:%d) Error opening file: %s\n", - __FILE__, - __LINE__, - fileName.c_str()); - return 0; - } - - _head->saveToFile (&file); - file.close(); - return 1; -} - -// set [section]/key to int value -#define TMPBUFSIZE 32 -int -ConfigurationTree::setValue (const string& section, const string& key, int value) { - char tmpBuf[TMPBUFSIZE]; - - // Make string from int - bzero(tmpBuf, TMPBUFSIZE); - snprintf (tmpBuf, TMPBUFSIZE - 1, "%d", (int) value); - - return setValue(section, key, tmpBuf); -} - -// set [section]/key to "value" -int -ConfigurationTree::setValue (const string& section, const string& key, - const string& value) { - - if (_head != NULL) { - ConfigSection *list; - ConfigItem *item; - - list = _head->getItemByKey(section); - item = list->head(); - - if (item == NULL) { - // getItemByKey creates a new section if it does not exist. - // If this is a new section, create its contents - list->setHead(new ConfigItem(key,value)); - } else { - // Section already exists, set 'key' to 'value' - item->setValueByKey(key,value); - } - - } else { - // Create the first section : - // And its first item : - _head = new ConfigItem (section); - _head->setHead(new ConfigItem(key, value)); - } - - return 1; -} - -// get [section]/key's value -string -ConfigurationTree::getValue (const string& section, const string& key) { - if (_head != NULL) { - string *valuePtr; - if (_head->getItemByKey(section)->head() != 0) { - // If config file exist - valuePtr = _head->getItemByKey(section)->head()->getValueByKey(key); - } else { - // If config-file not exist - valuePtr = _head->getItemByKey(section)->getValueByKey(key); - } - - if (valuePtr != NULL) { - return valuePtr->data(); - } else { - return ""; - } - } else { - return ""; - } -} - - -// EOF diff --git a/src/configurationtree.h b/src/configurationtree.h deleted file mode 100644 index 81d91fdff8..0000000000 --- a/src/configurationtree.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (C) 2004-2005 Savoir-Faire Linux inc. - * Author: Jerome Oufella <jerome.oufella@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. - */ - - -// The configuration tree holds all the runtime parameters for sflphone. -// -// Its _head pointer is a list of N Sections, N >= 0 -// Each Section holds M ConfigItems, M >= 0 -// -// Each Section or Item's name is stored in its _key pointer. -// -// It looks like that : -// -// HEAD _______________ _next -// ---| ConfigSection |------->...-->NULL -// |_______________| -// | _head -// _|________ -// |ConfigItem| -// |__________|--_next->...--->NULL -// - -#ifndef __CONFIGURATION_TREE_H__ -#define __CONFIGURATION_TREE_H__ - -#include "configitem.h" - -class ConfigurationTree { -public: - ConfigurationTree (void); - ConfigurationTree (const string&); - ~ConfigurationTree (void); - ConfigSection* head (void) { return this->_head; } - int populateFromFile(const string& ); - int saveToFile (const string& ); - int setValue (const string& , const string& , int); - int setValue(const string& , const string& , const string& ); - string getValue (const string& , const string& ); - -private: - ConfigSection *_head; -}; - -#endif // __CONFIGURATION_TREE_H__ - -// EOF diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 1fba455958..e4e751dc8b 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,8 +1,16 @@ if NEWGUI_CODE officialdir = official endif +if MAINTENER_CODE +serverdir = server +serverlib = server/libsflphoneguiserver.la +else +serverdir = qt +serverlib = qt/libsflphoneqt.la +endif + -SUBDIRS = $(officialdir) qt server +SUBDIRS = $(officialdir) $(serverdir) noinst_LTLIBRARIES = libguiframework.la @@ -10,4 +18,4 @@ libguiframework_la_SOURCES = guiframework.cpp guiframework.h libguiframework_la_CPPFLAGS = -I$(top_srcdir) libguiframework_la_CXXFLAGS = $(libccext2_CFLAGS) -libguiframework_la_LIBADD = qt/libsflphoneqt.la server/libsflphoneguiserver.la +libguiframework_la_LIBADD = $(serverlib) diff --git a/src/gui/guiframework.h b/src/gui/guiframework.h index 9c4a4411e9..7bc27b2001 100644 --- a/src/gui/guiframework.h +++ b/src/gui/guiframework.h @@ -42,7 +42,6 @@ public: virtual void displayError (const std::string& error) = 0; virtual void displayStatus (const std::string& status) = 0; virtual void displayContext (short id) = 0; - virtual std::string getRingtoneFile (void) = 0; virtual void setup (void) = 0; //virtual int selectedCall (void) = 0; //virtual bool isCurrentId (short) = 0; diff --git a/src/gui/qt/point.cpp b/src/gui/qt/point.cpp index c6ce45bacb..d5be368fc4 100644 --- a/src/gui/qt/point.cpp +++ b/src/gui/qt/point.cpp @@ -21,6 +21,7 @@ #include <string> #include "../../skin.h" +#include <iostream> using namespace std; /** @@ -70,6 +71,7 @@ Point::Point (const std::string& filename) { opened = _config.populateFromFile (filename); if (opened != 1) { // If opening failed, stop the application + std::cerr << "Fatal Error: Unable to open skin configuration file\n"; exit(0); } } diff --git a/src/gui/qt/qtGUImainwindow.cpp b/src/gui/qt/qtGUImainwindow.cpp index 6e8f96c46e..5e7804d484 100644 --- a/src/gui/qt/qtGUImainwindow.cpp +++ b/src/gui/qt/qtGUImainwindow.cpp @@ -630,15 +630,9 @@ QtGUIMainWindow::putOnHoldBusyLine (int line) void QtGUIMainWindow::dialtone (bool var) { - if (Manager::instance().isDriverLoaded()) { - if (_dialtone != var) { - _dialtone = var; - } - Manager::instance().setZonetone(var); - Manager::instance().getTonegenerator()->toneHandle(ZT_TONE_DIALTONE); - } else { - Manager::instance().error()->errorName(OPEN_FAILED_DEVICE); - } + if (var) { + Manager::instance().playTone(); + } } void diff --git a/src/gui/server/guiserverimpl.cpp b/src/gui/server/guiserverimpl.cpp index c9fc79525d..e96bbe0bed 100644 --- a/src/gui/server/guiserverimpl.cpp +++ b/src/gui/server/guiserverimpl.cpp @@ -378,12 +378,6 @@ GUIServerImpl::displayContext (short id) _requestManager.sendResponse(ResponseMessage("700", seq, responseMessage.str())); } -std::string -GUIServerImpl::getRingtoneFile (void) -{ - return std::string(""); -} - void GUIServerImpl::setup (void) { diff --git a/src/gui/server/guiserverimpl.h b/src/gui/server/guiserverimpl.h index 0d16532d36..ba242286a4 100644 --- a/src/gui/server/guiserverimpl.h +++ b/src/gui/server/guiserverimpl.h @@ -51,7 +51,6 @@ public: void displayError (const std::string& error); void displayStatus (const std::string& status); void displayContext (short id); - std::string getRingtoneFile (void); void setup (void); //void startVoiceMessageNotification (void); //void stopVoiceMessageNotification (void); diff --git a/src/gui/server/request.cpp b/src/gui/server/request.cpp index 8c29137917..4f43d1686c 100644 --- a/src/gui/server/request.cpp +++ b/src/gui/server/request.cpp @@ -169,7 +169,7 @@ RequestPlayTone::execute() if ( GUIServer::instance().playTone() ) { return message("200", "OK"); } - return message("500", "DTMF Error"); + return message("500", "Tone Error"); } ResponseMessage diff --git a/src/gui/server/requestconfig.cpp b/src/gui/server/requestconfig.cpp index e0cdab5aad..0df8b23de9 100644 --- a/src/gui/server/requestconfig.cpp +++ b/src/gui/server/requestconfig.cpp @@ -102,7 +102,8 @@ RequestConfigGet::execute() if (GUIServer::instance().getConfig(_section, _name, arg)) { return message("200", arg); } else { - return message("500","Server Error"); + // 402 seq10001 Variable unknown + return message("402","Variable unknown"); } } diff --git a/src/gui/server/tcpsessionio.cpp b/src/gui/server/tcpsessionio.cpp index 4acf996a24..b1faef4bcc 100644 --- a/src/gui/server/tcpsessionio.cpp +++ b/src/gui/server/tcpsessionio.cpp @@ -1,14 +1,21 @@ -// -// C++ Implementation: tcpsessionio -// -// Description: -// -// -// Author: Yan Morin <yan.morin@savoirfairelinux.com>, (C) 2005 -// -// Copyright: See COPYING file that comes with this distribution -// -// +/** + * Copyright (C) 2005 Savoir-Faire Linux inc. + * Author: Yan Morin <yan.morin@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 "tcpsessionio.h" const int TCPSessionIO::PORT = 3999; diff --git a/src/gui/server/tcpsessionio.h b/src/gui/server/tcpsessionio.h index b76d8991aa..1a2772592c 100644 --- a/src/gui/server/tcpsessionio.h +++ b/src/gui/server/tcpsessionio.h @@ -1,14 +1,21 @@ -// -// C++ Interface: tcpsessionio -// -// Description: -// -// -// Author: Yan Morin <yan.morin@savoirfairelinux.com>, (C) 2005 -// -// Copyright: See COPYING file that comes with this distribution -// -// +/** + * Copyright (C) 2005 Savoir-Faire Linux inc. + * Author: Yan Morin <yan.morin@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. + */ #ifndef TCPSESSIONIO_H #define TCPSESSIONIO_H diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 71ad81aa53..cc7dbf2aff 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -42,7 +42,6 @@ #include "audio/codecDescriptor.h" #include "audio/ringbuffer.h" #include "audio/tonegenerator.h" -#include "audio/dtmf.h" #include "call.h" #include "error.h" #include "user_cfg.h" @@ -95,6 +94,8 @@ ManagerImpl::ManagerImpl (void) _spkr_volume = 0; _mic_volume = 0; _mic_volume_before_mute = 0; + + _toneType = 0; } ManagerImpl::~ManagerImpl (void) @@ -206,13 +207,6 @@ ManagerImpl::initGui() { } } - -ToneGenerator* -ManagerImpl::getTonegenerator (void) -{ - return _tone; -} - Error* ManagerImpl::error (void) { @@ -307,15 +301,16 @@ ManagerImpl::pushBackNewCall (short id, enum CallType type) void ManagerImpl::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++; - } - } + CallVector::iterator iter = _callVector.begin(); + + while(iter!=_callVector.end()) { + if ((*iter)->getId() == id) { + delete (*iter); + _callVector.erase(iter); + return; + } + iter++; + } } /////////////////////////////////////////////////////////////////////////////// @@ -356,18 +351,13 @@ ManagerImpl::hangupCall (short id) } call->setStatus(string(HUNGUP_STATUS)); call->setState(Hungup); + + int result = call->hangup(); + _mutex.enterMutex(); _nCalls -= 1; _mutex.leaveMutex(); deleteCall(id); - if (getbRingback()) { - ringback(false); - } - if (getbRingtone()) { - ringtone(false); - } - int result = call->hangup(); - congestion(false); return result; } @@ -385,9 +375,7 @@ ManagerImpl::cancelCall (short id) _nCalls -= 1; _mutex.leaveMutex(); deleteCall(id); - if (getbRingback()) { - ringback(false); - } + stopTone(); return call->cancel(); } @@ -401,8 +389,8 @@ ManagerImpl::answerCall (short id) return -1; call->setStatus(string(CONNECTED_STATUS)); call->setState(Answered); - ringtone(false); + stopTone(); switchCall(id); return call->answer(); } @@ -480,6 +468,7 @@ ManagerImpl::muteOff (short id) int ManagerImpl::refuseCall (short id) { + stopTone(); Call *call; call = getCall(id); if (call == NULL) @@ -491,13 +480,15 @@ ManagerImpl::refuseCall (short id) call->setStatus(string(HUNGUP_STATUS)); call->setState(Refused); - ringtone(false); + _mutex.enterMutex(); _nCalls -= 1; _mutex.leaveMutex(); - deleteCall(id); + setCurrentCallId(0); - return call->refuse(); + int refuse = call->refuse(); + deleteCall(id); + return refuse; } int @@ -578,13 +569,14 @@ ManagerImpl::sendDtmf (short id, char code) bool ManagerImpl::playDtmf(char code) { + stopTone(); + int16* _buf = new int16[SIZEBUF]; bool returnValue = false; // Handle dtmf - DTMF key; - key.startTone(code); - if ( key.generateDTMF(_buf, SAMPLING_RATE) ) { + _key.startTone(code); + if ( _key.generateDTMF(_buf, SAMPLING_RATE) ) { int k, spkrVolume; int16* buf_ctrl_vol; @@ -603,20 +595,23 @@ ManagerImpl::playDtmf(char code) } AudioLayer *audiolayer = getAudioDriver(); + _mutex.enterMutex(); audiolayer->urgentRingBuffer().flush(); - + // Put buffer to urgentRingBuffer audiolayer->urgentRingBuffer().Put(buf_ctrl_vol, size * CHANNELS); - + // We activate the stream if it's not active yet. if (!audiolayer->isStreamActive()) { audiolayer->startStream(); audiolayer->sleep(pulselen); - audiolayer->stopStream(); audiolayer->urgentRingBuffer().flush(); + audiolayer->stopStream(); } else { audiolayer->sleep(pulselen); } + _mutex.leaveMutex(); + //setZonetone(false); delete[] buf_ctrl_vol; returnValue = true; } @@ -624,12 +619,6 @@ ManagerImpl::playDtmf(char code) return returnValue; } -bool -ManagerImpl::playTone() -{ - return true; -} - /////////////////////////////////////////////////////////////////////////////// // Management of event peer IP-phone /////////////////////////////////////////////////////////////////////////////// @@ -662,57 +651,47 @@ ManagerImpl::incomingCall (short id) void ManagerImpl::peerAnsweredCall (short id) { - Call* call; + stopTone(); - if (getbRingback()) { - ringback(false); - } - call = getCall(id); - call->setStatus(string(CONNECTED_STATUS)); + Call* call = getCall(id); + call->setStatus(string(CONNECTED_STATUS)); + call->setState(Answered); - call->setState(Answered); - //if (isCurrentId(id)) { + // switch current call switchCall(id); _gui->peerAnsweredCall(id); - //} } -int +int ManagerImpl::peerRingingCall (short id) { - Call* call; - - call = getCall(id); - call->setStatus(string(RINGING_STATUS)); - call->setState(Ringing); + Call* call = getCall(id); + call->setStatus(string(RINGING_STATUS)); + call->setState(Ringing); - ringback(true); - _gui->peerRingingCall(id); - displayStatus(RINGING_STATUS); - return 1; + // ring + ringback(true); + _gui->peerRingingCall(id); + return 1; } int ManagerImpl::peerHungupCall (short id) { - Call* call; + stopTone(); + Call* call = getCall(id); + call->setStatus(string(HUNGUP_STATUS)); + call->setState(Hungup); - call = getCall(id); - call->setStatus(string(HUNGUP_STATUS)); - call->setState(Hungup); - _gui->peerHungupCall(id); - if (getbRingback()) { - ringback(false); - } - if (getbRingtone()) { - ringtone(false); - } - _mutex.enterMutex(); - _nCalls -= 1; - _mutex.leaveMutex(); - deleteCall(id); + _gui->peerHungupCall(id); + + // end up call + _mutex.enterMutex(); + _nCalls -= 1; + _mutex.leaveMutex(); + deleteCall(id); setCurrentCallId(0); - return 1; + return 1; } void @@ -785,75 +764,78 @@ ManagerImpl::stopVoiceMessageNotification (void) _gui->sendVoiceNbMessage(std::string("0")); } +bool +ManagerImpl::playATone(unsigned int tone) { + if (isDriverLoaded()) { + ost::MutexLock m(_toneMutex); + _toneType = tone; + _tone->toneHandle(_toneType, getConfigString(PREFERENCES, ZONE_TONE)); + return true; + } + return false; +} + +void +ManagerImpl::stopTone() { + if (isDriverLoaded()) { + ost::MutexLock m(_toneMutex); + _toneType = ZT_TONE_NULL; + _tone->stopTone(); + _mutex.enterMutex(); + getAudioDriver()->stopStream(); + _mutex.leaveMutex(); + } +} + +bool +ManagerImpl::playTone() +{ + return playATone(ZT_TONE_DIALTONE); +} + void ManagerImpl::congestion (bool var) { - if (isDriverLoaded()) { - if (_congestion != var) { - _congestion = var; - } - _zonetone = var; - _debug("ManagerImpl::congestion : Tone Handle Congestion\n"); - _tone->toneHandle(ZT_TONE_CONGESTION); - } else { - _error->errorName(OPEN_FAILED_DEVICE); - } + playATone(ZT_TONE_CONGESTION); } void ManagerImpl::ringback (bool var) { - if (isDriverLoaded()) { - if (_ringback != var) { - _ringback = var; - } - _zonetone = var; - _tone->toneHandle(ZT_TONE_RINGTONE); - } else { - _error->errorName(OPEN_FAILED_DEVICE); - } + playATone(ZT_TONE_RINGTONE); +} +void +ManagerImpl::busy() { + playATone(ZT_TONE_BUSY); } void -ManagerImpl::ringtone (bool var) +ManagerImpl::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()); - } - _ringtone = var; - _zonetone = var; - if (getNumberOfCalls() == 1) { - // If just one line is ringing - _tone->playRingtone((_gui->getRingtoneFile()).data()); - } - } else { - _error->errorName(OPEN_FAILED_DEVICE); - } + playATone(ZT_TONE_RINGTONE); // not a file... } +/** + * Use Urgent Buffer + */ void ManagerImpl::notificationIncomingCall (void) { - int16* buf_ctrl_vol; - int16* buffer = new int16[SAMPLING_RATE]; - int size = SAMPLES_SIZE(FRAME_PER_BUFFER);//SAMPLING_RATE/2; - int k, spkrVolume; - - _tone->generateSin(440, 0, buffer); - - // Volume Control - buf_ctrl_vol = new int16[size*CHANNELS]; - 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, - SAMPLES_SIZE(FRAME_PER_BUFFER)); + int16* buf_ctrl_vol; + int16* buffer = new int16[SAMPLING_RATE]; + int size = SAMPLES_SIZE(FRAME_PER_BUFFER);//SAMPLING_RATE/2; + int k, spkrVolume; + + _tone->generateSin(440, 0, buffer); + + // Volume Control + buf_ctrl_vol = new int16[size*CHANNELS]; + 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()->putUrgent(buf_ctrl_vol, SAMPLES_SIZE(FRAME_PER_BUFFER)); - delete[] buf_ctrl_vol; - delete[] buffer; + delete[] buf_ctrl_vol; + delete[] buffer; } void @@ -863,7 +845,7 @@ ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr) { char* addr; char to[16]; bzero (to, 16); - + int fd3, fd4; bool ok = stunOpenSocketPair(stunSvrAddr, &mappedAddr, @@ -1004,7 +986,6 @@ ManagerImpl::initConfigFile (void) fill_config_int(SEND_DTMF_AS, SIP_INFO_STR); fill_config_str(STUN_SERVER, DFT_STUN_SERVER); fill_config_int(USE_STUN, NO_STR); - fill_config_int(LOCAL_IP, LOCAL_IP_DEFAULT); section = AUDIO; fill_config_int(DRIVER_NAME, DFT_DRIVER_STR); @@ -1274,7 +1255,6 @@ ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& nam { bool returnValue = false; if (name=="") { - returnValue = true; } else if (name=="") { returnValue = true; diff --git a/src/managerimpl.h b/src/managerimpl.h index 09e26e4e44..50c20cf4ea 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -29,6 +29,7 @@ #include "audio/audiodevice.h" #include "observer.h" #include "config/config.h" +#include "audio/dtmf.h" class AudioLayer; class CodecDescriptor; @@ -70,10 +71,10 @@ typedef std::vector< CodecDescriptor* > CodecDescriptorVector; /* * Structure for audio device */ -struct device_t{ - const char* hostApiName; - const char* deviceName; -}; +//struct device_t{ +// const char* hostApiName; +// const char* deviceName; +//}; /** * To send multiple string @@ -92,9 +93,6 @@ public: // Set the graphic user interface void setGui (GuiFramework* gui); - // Accessor to tonegenerator - ToneGenerator* getTonegenerator(void); - // Accessor to error Error* error(void); @@ -126,8 +124,8 @@ public: CodecDescriptorVector* getCodecDescVector(void); // Handle specified ring tone - inline bool getZonetone (void) { return _zonetone; } - inline void setZonetone (bool b) { _zonetone = b; } + inline bool getZonetone (void) { ost::MutexLock m(_toneMutex); return _zonetone; } + inline void setZonetone (bool b) { ost::MutexLock m(_toneMutex); _zonetone = b; } /* * Attribute a new random id for a new call @@ -220,8 +218,8 @@ name); * Handle played music when an incoming call occurs */ void ringtone (bool var); - void congestion (bool var); + void busy(); /* * Notification of incoming call when you are already busy @@ -245,10 +243,10 @@ name); /* * Inline functions to manage volume control */ - inline int getSpkrVolume (void) { return _spkr_volume; } - inline void setSpkrVolume (int spkr_vol) { _spkr_volume = spkr_vol; } - inline int getMicroVolume (void) { return _mic_volume; } - inline void setMicroVolume (int mic_vol) { _mic_volume = _mic_volume_before_mute = mic_vol; } + inline int getSpkrVolume (void) { ost::MutexLock m(_mutex); return _spkr_volume; } + inline void setSpkrVolume (int spkr_vol) { ost::MutexLock m(_mutex); _spkr_volume = spkr_vol; } + inline int getMicroVolume (void) { ost::MutexLock m(_mutex); return _mic_volume; } + inline void setMicroVolume (int mic_vol) { ost::MutexLock m(_mutex); _mic_volume = _mic_volume_before_mute = mic_vol; } /* * Manage information about firewall @@ -260,7 +258,7 @@ name); /* * Manage information about audio driver */ - inline bool isDriverLoaded (void) { return _loaded; } + inline bool isDriverLoaded (void) const { return _loaded; } inline void loaded (bool l) { _loaded = l; } /* @@ -318,14 +316,25 @@ private: * Init the volume for speakers/micro from 0 to 100 value */ void initVolume(); + + /* + * Play one tone + * @return false if the driver is uninitialize + */ + bool playATone(unsigned int tone); + void stopTone(); ///////////////////// // Private variables ///////////////////// ToneGenerator* _tone; + ost::Mutex _toneMutex; + int _toneType; + Error* _error; GuiFramework* _gui; AudioLayer* _audiodriverPA; + DTMF _key; /* * Vector of VoIPLink @@ -345,7 +354,7 @@ private: /* * Mutex to protect access to code section */ - ost::Mutex _mutex; + ost::Mutex _mutex; unsigned int _nCalls; short _currentCallId; diff --git a/src/sipcall.cpp b/src/sipcall.cpp index 90972b4860..2e0ee55e90 100644 --- a/src/sipcall.cpp +++ b/src/sipcall.cpp @@ -34,7 +34,7 @@ using namespace std; -SipCall::SipCall (short id, CodecDescriptorVector* cdv) +SipCall::SipCall (short id, CodecDescriptorVector* cdv) : _localIp("127.0.0.1") { _id = id; // Same id of Call object _cid = 0; // call id, from the sipvoiplink @@ -60,6 +60,8 @@ SipCall::SipCall (short id, CodecDescriptorVector* cdv) SipCall::~SipCall (void) { dealloc(); + delete _audiocodec; + _audiocodec = NULL; } void @@ -143,22 +145,20 @@ SipCall::getAudioCodec (void) void SipCall::setAudioCodec (AudioCodec* ac) { + // it use a new! + delete _audiocodec; _audiocodec = ac; } // newIncomingCall is called when the IP-Phone user receives a new call. int SipCall::newIncomingCall (eXosip_event_t *event) { - SipCall *ca = this; - - sdp_message_t *remote_sdp = NULL; _cid = event->cid; _did = event->did; _tid = event->tid; if (_did < 1 && _cid < 1) { - exit(0); return -1; /* not enough information for this event?? */ } @@ -179,6 +179,7 @@ SipCall::newIncomingCall (eXosip_event_t *event) { } } + sdp_message_t *remote_sdp = NULL; /* negotiate payloads */ if (event->request != NULL) { remote_sdp = eXosip_get_sdp_info (event->request); @@ -207,8 +208,8 @@ SipCall::newIncomingCall (eXosip_event_t *event) { if (remote_med == NULL || remote_med->m_port == NULL) { /* no audio media proposed */ // Send 415 Unsupported media type - eXosip_call_send_answer (_tid, 415, NULL); - sdp_message_free (remote_sdp); + eXosip_call_send_answer (_tid, 415, NULL); + sdp_message_free (remote_sdp); return 0; } @@ -230,7 +231,7 @@ SipCall::newIncomingCall (eXosip_event_t *event) { } } if (tmp != NULL) { - ca->payload = atoi (tmp); + payload = atoi (tmp); } else { // Send 415 Unsupported media type eXosip_call_send_answer (_tid, 415, NULL); @@ -238,9 +239,9 @@ SipCall::newIncomingCall (eXosip_event_t *event) { return 0; } - if (tmp != NULL && (ca->payload == 0 || ca->payload == 8) + if (tmp != NULL && (payload == 0 || payload == 8) && _remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') { - } + } } if (remote_sdp != NULL) { /* TODO: else build an offer */ @@ -257,10 +258,10 @@ SipCall::newIncomingCall (eXosip_event_t *event) { eXosip_call_send_answer (_tid, 415, NULL); } else { /* start sending audio */ - if (ca->enable_audio > 0) { - ca->enable_audio = -1; + if (enable_audio > 0) { + enable_audio = -1; } - if (ca->enable_audio != 1) /* audio is started */ { + if (enable_audio != 1) /* audio is started */ { sdp_message_t *local_sdp; local_sdp = eXosip_get_sdp_info (answer); if (remote_sdp != NULL && local_sdp != NULL) { @@ -289,9 +290,9 @@ SipCall::newIncomingCall (eXosip_event_t *event) { tmp = (char *) osip_list_get (local_med->m_payloads, 0); } if (tmp != NULL) { - ca->payload = atoi (tmp); - _debug("SipCall::newIncomingCall: For incoming payload = %d\n", ca->payload); - setAudioCodec(_cdv->at(0)->alloc(ca->payload, "")); + payload = atoi (tmp); + _debug("SipCall::newIncomingCall: For incoming payload = %d\n", payload); + setAudioCodec(_cdv->at(0)->alloc(payload, "")); } if (tmp != NULL && audio_port > 0 @@ -324,41 +325,40 @@ SipCall::newIncomingCall (eXosip_event_t *event) { eXosip_unlock (); } - this->_state = event->type; - sdp_message_free (remote_sdp); - return 0; + _state = event->type; + sdp_message_free (remote_sdp); + return 0; } int SipCall::ringingCall (eXosip_event_t *event) { - SipCall* ca = this; - - this->_cid = event->cid; - this->_did = event->did; - this->_tid = event->tid; - - if (this->_did < 1 && this->_cid < 1) { - return -1; - } - osip_strncpy (_textinfo, event->textinfo, 255); + this->_cid = event->cid; + this->_did = event->did; + this->_tid = event->tid; - if (event->response != NULL) { - _status_code = event->response->status_code; - snprintf (_reason_phrase, 49, "%s", event->response->reason_phrase); - } + if (this->_did < 1 && this->_cid < 1) { + return -1; + } - if (event->request != NULL) { - char *tmp = NULL; + osip_strncpy (_textinfo, event->textinfo, 255); - osip_from_to_str (event->request->from, &tmp); - if (tmp != NULL) { - snprintf (_remote_uri, 255, "%s", tmp); - osip_free (tmp); - } - } + if (event->response != NULL) { + _status_code = event->response->status_code; + snprintf (_reason_phrase, 49, "%s", event->response->reason_phrase); + } + + if (event->request != NULL) { + char *tmp = NULL; + osip_from_to_str (event->request->from, &tmp); + if (tmp != NULL) { + snprintf (_remote_uri, 255, "%s", tmp); + osip_free (tmp); + } + } +/* sdp_message_t *remote_sdp; sdp_message_t *local_sdp; @@ -366,7 +366,7 @@ SipCall::ringingCall (eXosip_event_t *event) { remote_sdp = eXosip_get_sdp_info (event->response); if (remote_sdp == NULL) { _debug("SipCall::ringingCall: No remote SDP body found for call\n"); - /* TODO: remote_sdp = retreive from ack above */ + // TODO: remote_sdp = retreive from ack above } if (local_sdp == NULL) { _debug("SipCall::ringingCall: SDP body was probably in the ACK (TODO)\n"); @@ -401,7 +401,7 @@ SipCall::ringingCall (eXosip_event_t *event) { && audio_port > 0 && _remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') { - /* search if stream is sendonly or recvonly */ + // search if stream is sendonly or recvonly _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med); _local_sendrecv = sdp_analyse_attribute (local_sdp, local_med); @@ -415,7 +415,7 @@ SipCall::ringingCall (eXosip_event_t *event) { } sdp_message_free (local_sdp); sdp_message_free (remote_sdp); - +*/ this->_state = event->type;; return 0; } @@ -423,11 +423,9 @@ SipCall::ringingCall (eXosip_event_t *event) { int SipCall::receivedAck (eXosip_event_t *event) { - SipCall *ca = this; - - _cid = event->cid; - _did = event->did; - + _cid = event->cid; + _did = event->did; +/* if (event->ack != NULL) { sdp_message_t *remote_sdp; remote_sdp = eXosip_get_sdp_info (event->ack); @@ -438,7 +436,7 @@ SipCall::receivedAck (eXosip_event_t *event) } } - if (ca->enable_audio != 1) { /* audio is started */ + if (enable_audio != 1) { // audio is started sdp_message_t *remote_sdp; sdp_message_t *local_sdp; @@ -479,7 +477,7 @@ SipCall::receivedAck (eXosip_event_t *event) && _remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') { - /* search if stream is sendonly or recvonly */ + // search if stream is sendonly or recvonly _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med); _local_sendrecv = sdp_analyse_attribute (local_sdp, local_med); @@ -494,20 +492,21 @@ SipCall::receivedAck (eXosip_event_t *event) sdp_message_free (local_sdp); sdp_message_free (remote_sdp); } - +*/ _state = event->type; return 0; } + + int SipCall::answeredCall(eXosip_event_t *event) { _cid = event->cid; _did = event->did; - - if (_did < 1 && _cid < 1) { - exit(0); - return -1; /* not enough information for this event?? */ - } + + if (_did < 1 && _cid < 1) { + return -1; /* not enough information for this event?? */ + } osip_strncpy(this->_textinfo, event->textinfo, 255); if (event->response != NULL) { @@ -548,8 +547,8 @@ SipCall::answeredCall(eXosip_event_t *event) { _debug("SipCall::answeredCall: Cannot complete ACK with sdp body?!\n"); } } - sdp_message_free (local_sdp); - sdp_message_free (remote_sdp); + sdp_message_free (local_sdp); + sdp_message_free (remote_sdp); eXosip_call_send_ack (_did, ack); } @@ -563,34 +562,33 @@ SipCall::answeredCall(eXosip_event_t *event) { void SipCall::answeredCall_without_hold (eXosip_event_t *event) { - SipCall *ca = this; - - if (ca->enable_audio == 1 && event->response != NULL) { + if (enable_audio == 1 && event->response != NULL) { sdp_message_t *sdp = eXosip_get_sdp_info (event->response); if (sdp != NULL) { /* audio is started and session has just been modified */ - ca->enable_audio = -1; + enable_audio = -1; sdp_message_free (sdp); } } - if (ca->enable_audio != 1) { /* audio is started */ - sdp_connection_t *conn; - sdp_media_t *remote_med; - char *tmp = NULL; + if (enable_audio != 1 && + event->request != NULL && + event->response != NULL) { /* audio is started */ sdp_message_t *local_sdp = eXosip_get_sdp_info (event->request); sdp_message_t *remote_sdp = eXosip_get_sdp_info (event->response); + sdp_media_t *remote_med = NULL; + char *tmp = NULL; if (remote_sdp == NULL) { _debug("SipCall::answeredCall_without_hold: No remote SDP body found for call\n"); /* TODO: remote_sdp = retreive from ack above */ } else { - - conn = eXosip_get_audio_connection (remote_sdp); + sdp_connection_t *conn = eXosip_get_audio_connection (remote_sdp); if (conn != NULL && conn->c_addr != NULL) { snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr); } + remote_med = eXosip_get_audio_media (remote_sdp); if (remote_med != NULL && remote_med->m_port != NULL) { _remote_sdp_audio_port = atoi (remote_med->m_port); @@ -602,11 +600,10 @@ SipCall::answeredCall_without_hold (eXosip_event_t *event) } if (tmp != NULL) { - ca->payload = atoi (tmp); - _debug("SipCall::answeredCall_without_hold: For outgoing call: ca->payload = %d\n", ca->payload); - setAudioCodec(_cdv->at(0)->alloc(ca->payload, "")); + payload = atoi (tmp); + _debug("SipCall::answeredCall_without_hold: For outgoing call: ca->payload = %d\n", payload); + setAudioCodec(_cdv->at(0)->alloc(payload, "")); } - } if (local_sdp == NULL) { @@ -614,10 +611,8 @@ SipCall::answeredCall_without_hold (eXosip_event_t *event) } if (remote_sdp != NULL && local_sdp != NULL) { - sdp_media_t *local_med; int audio_port = 0; - - local_med = eXosip_get_audio_media (local_sdp); + sdp_media_t *local_med = eXosip_get_audio_media (local_sdp); if (local_med != NULL && local_med->m_port != NULL) { audio_port = atoi (local_med->m_port); } diff --git a/src/sipcall.h b/src/sipcall.h index 53440b6a9e..649ec244c9 100644 --- a/src/sipcall.h +++ b/src/sipcall.h @@ -24,6 +24,7 @@ #include <eXosip2/eXosip.h> #include <vector> +#include <string> class CodecDescriptor; class AudioCodec; @@ -69,6 +70,9 @@ public: void setLocalAudioPort (int); int getLocalAudioPort (void); + std::string getLocalIp() { return _localIp; } + void setLocalIp(const std::string& ip) { _localIp = ip; } + /* * Manage id, did (dialog-id), cid (call-id) and tid (transaction-id) * for each sipcall @@ -138,6 +142,7 @@ private: int _remote_sdp_audio_port; int _local_sendrecv; /* _SENDRECV, _SENDONLY, _RECVONLY */ int _remote_sendrecv; /* _SENDRECV, _SENDONLY, _RECVONLY */ + std::string _localIp; }; #endif // __SIP_CALL_H__ diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 9494f757df..d50f85f701 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -18,13 +18,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -//#include <sys/time.h> +#include <string> -#include <eXosip2/eXosip.h> +#include <eXosip2/eXosip.h> #include <osip2/osip.h> -#include <string> - #include "sipvoiplink.h" #include "global.h" #include "audio/codecDescriptor.h" @@ -34,7 +32,6 @@ #include "user_cfg.h" #include "eventthread.h" - using namespace ost; using namespace std; @@ -49,11 +46,12 @@ using namespace std; SipVoIPLink::SipVoIPLink (short id) : VoIPLink (id) { - setId(id); + // default _audioRTP object initialization + _evThread = new EventThread(this); _localPort = 0; - _reg_id = -1; _nMsgVoicemail = 0; - _evThread = new EventThread(this); + _reg_id = -1; + // defautlt _sipcallVector object initialization } SipVoIPLink::~SipVoIPLink(void) { @@ -103,8 +101,7 @@ SipVoIPLink::init (void) return 0; } - eXosip_masquerade_contact((Manager::instance().getFirewallAddress()).data(), - Manager::instance().getFirewallPort()); + eXosip_masquerade_contact((Manager::instance().getFirewallAddress()).data(), Manager::instance().getFirewallPort()); } @@ -129,22 +126,20 @@ void SipVoIPLink::terminate(void) { delete _evThread; - eXosip_quit(); + eXosip_quit(); } int SipVoIPLink::setRegister (void) { ManagerImpl& manager = Manager::instance(); + _debug("SipVoIPLink::setRegister()\n"); - int i; - osip_message_t *reg = NULL; // all this will be inside the profil associate with the voip link - string proxy = "sip:" + manager.getConfigString(SIGNALISATION, PROXY); - string hostname = "sip:" + manager.getConfigString(SIGNALISATION, HOST_PART); - string from = fromHeader(manager.getConfigString(SIGNALISATION, USER_PART), - manager.getConfigString(SIGNALISATION, HOST_PART)); + std::string proxy = "sip:" + manager.getConfigString(SIGNALISATION, PROXY); + std::string hostname = "sip:" + manager.getConfigString(SIGNALISATION, HOST_PART); + std::string from = fromHeader(manager.getConfigString(SIGNALISATION, USER_PART), manager.getConfigString(SIGNALISATION, HOST_PART)); if (manager.getConfigString(SIGNALISATION, HOST_PART).empty()) { manager.error()->errorName(HOST_PART_FIELD_EMPTY); @@ -155,14 +150,14 @@ SipVoIPLink::setRegister (void) return -1; } - eXosip_lock(); if (setAuthentication() == -1) { _debug("No authentication\n"); - eXosip_unlock(); return -1; } - + _debug("REGISTER From: %s\n", from.data()); + osip_message_t *reg = NULL; + eXosip_lock(); if (!manager.getConfigString(SIGNALISATION, PROXY).empty()) { _reg_id = eXosip_register_build_initial_register ((char*)from.data(), (char*)proxy.data(), NULL, EXPIRES_VALUE, ®); @@ -175,7 +170,7 @@ SipVoIPLink::setRegister (void) return -1; } - i = eXosip_register_send_register (_reg_id, reg); + int i = eXosip_register_send_register (_reg_id, reg); if (i == -2) { _debug("cannot build registration, check the setup\n"); eXosip_unlock(); @@ -186,7 +181,6 @@ SipVoIPLink::setRegister (void) eXosip_unlock(); return -1; } - eXosip_unlock(); manager.error()->setError(0); @@ -197,8 +191,7 @@ SipVoIPLink::setRegister (void) int SipVoIPLink::setUnregister (void) { - int i; - // int reg_id = -1; + int i = 0; osip_message_t *reg = NULL; eXosip_lock(); @@ -282,6 +275,9 @@ SipVoIPLink::outgoingInvite (short id, const string& to_url) } } +/** + * @return 0 is good, -1 is bad + */ int SipVoIPLink::answer (short id) { @@ -327,7 +323,7 @@ SipVoIPLink::answer (short id) // Incoming call is answered, start the sound channel. if (_audiortp.createNewSession (getSipCall(id)) < 0) { _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__); - exit(1); + i = -1; } return i; } @@ -388,8 +384,8 @@ SipVoIPLink::onhold (short id) return -1; } - eXosip_lock (); // Build INVITE_METHOD for put call on-hold + eXosip_lock (); i = eXosip_call_build_request (did, INVITE_METHOD, &invite); eXosip_unlock (); @@ -431,6 +427,9 @@ SipVoIPLink::onhold (short id) return i; } +/** + * @return 0 is good, -1 is bad + */ int SipVoIPLink::offhold (short id) { @@ -489,7 +488,7 @@ SipVoIPLink::offhold (short id) // Enable audio if (_audiortp.createNewSession (getSipCall(id)) < 0) { _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__); - exit(1); + i = -1; } return i; } @@ -554,27 +553,14 @@ SipVoIPLink::getEvent (void) return -1; } + int returnValue = 0; _debug("GetEvent : %d\n", event->type); switch (event->type) { // IP-Phone user receives a new call case EXOSIP_CALL_INVITE: // - // TODO: remove this hack, when there is no - // buffer overflow in event->request->bodies->body... - if (event->request!=NULL && event->request->bodies!=NULL) { - if (!osip_list_eol (event->request->bodies, 0)) { - osip_body_t* t = (osip_body_t *)osip_list_get (event->request->bodies, 0); - if (t!=NULL && t->body!=NULL) { - char *lastnewline = strrchr(t->body, '\n'); - if (lastnewline != NULL ) { - lastnewline++; - if (*lastnewline != '\0') { - _debug("EXOSIP_CALL_INVITE: request error patched\n"); } - *lastnewline = '\0'; - } - } - } - } + checkNetwork(); + // Set local random port for incoming call if (!Manager::instance().useStun()) { setLocalPort(RANDOM_LOCAL_PORT); @@ -583,7 +569,8 @@ SipVoIPLink::getEvent (void) if (behindNat() != 0) { setLocalPort(Manager::instance().getFirewallPort()); } else { - return -1; + returnValue = -1; + break; } } @@ -622,18 +609,20 @@ SipVoIPLink::getEvent (void) } } else { osip_from_free(from); - return -1; + returnValue = -1; + break; } _debug("From: %s\n", name); osip_from_free(from); + SipCall *sipcall = getSipCall(id); // Associate an audio port with a call - getSipCall(id)->setLocalAudioPort(_localPort); + sipcall->setLocalAudioPort(_localPort); + sipcall->setLocalIp(getLocalIpAddress()); - getSipCall(id)->newIncomingCall(event); + sipcall->newIncomingCall(event); if (Manager::instance().incomingCall(id) < 0) { Manager::instance().displayErrorText(id, "Incoming call failed"); - return -1; } break; @@ -641,8 +630,13 @@ SipVoIPLink::getEvent (void) eXosip_call_send_answer(event->tid, 403, NULL); break; + case EXOSIP_CALL_PROCEEDING: // 8 + // proceeding call... + break; + // The peer-user answers - case EXOSIP_CALL_ANSWERED: + case EXOSIP_CALL_ANSWERED: // 10 + { id = findCallId(event); if (id == 0) { id = findCallIdInitial(event); @@ -665,7 +659,8 @@ SipVoIPLink::getEvent (void) if (_audiortp.createNewSession (sipcall) < 0) { _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__); - exit(1); + returnValue = -1; + break; } } } else { @@ -676,11 +671,12 @@ SipVoIPLink::getEvent (void) } } break; - + } case EXOSIP_CALL_RINGING: //peer call is ringing id = findCallId(event); - //id = findCallIdWhenRinging(); - + if (id == 0) { + id = findCallIdInitial(event); + } _debug("Call is ringing [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did); @@ -688,7 +684,8 @@ SipVoIPLink::getEvent (void) getSipCall(id)->ringingCall(event); Manager::instance().peerRingingCall(id); } else { - return -1; + returnValue = -1; + break; } break; @@ -702,10 +699,11 @@ SipVoIPLink::getEvent (void) if (id > 0) { getSipCall(id)->receivedAck(event); } else { - return -1; + returnValue = -1; + break; } break; - + // The peer-user closed the phone call(we received BYE). case EXOSIP_CALL_CLOSED: id = findCallId(event); @@ -719,7 +717,8 @@ SipVoIPLink::getEvent (void) Manager::instance().peerHungupCall(id); deleteSipCall(id); } else { - return -1; + returnValue = -1; + break; } break; case EXOSIP_CALL_RELEASED: @@ -751,11 +750,14 @@ SipVoIPLink::getEvent (void) case REQ_TIMEOUT: case TEMP_UNAVAILABLE: case ADDR_INCOMPLETE: - case BUSY_HERE: // Display error on the screen phone //Manager::instance().displayError(event->response->reason_phrase); Manager::instance().displayErrorText(id, event->response->reason_phrase); Manager::instance().congestion(true); + break; + case BUSY_HERE: + Manager::instance().displayErrorText(id, event->response->reason_phrase); + Manager::instance().busy(); break; case REQ_TERMINATED: break; @@ -769,8 +771,7 @@ SipVoIPLink::getEvent (void) // Handle 5XX errors switch (event->response->status_code) { case SERVICE_UNAVAILABLE: - Manager::instance().ringback(false); - Manager::instance().congestion(true); + Manager::instance().congestion(true); break; default: break; @@ -782,15 +783,18 @@ SipVoIPLink::getEvent (void) switch (event->response->status_code) { case BUSY_EVERYWHERE: case DECLINE: - Manager::instance().ringback(false); - Manager::instance().congestion(true); + Manager::instance().congestion(true); break; default: break; } break; - case EXOSIP_REGISTRATION_SUCCESS: //1 + case EXOSIP_CALL_MESSAGE_NEW: // 18 + // TODO: + break; + + case EXOSIP_REGISTRATION_SUCCESS: // 1 Manager::instance().displayStatus(LOGGED_IN_STATUS); break; @@ -827,29 +831,34 @@ SipVoIPLink::getEvent (void) int ii; unsigned int pos; unsigned int pos_slash; - string *str; + std::string nb_msg; - osip_body_t *body; + osip_body_t *body = NULL; // Get the message body ii = osip_message_get_body(event->request, 0, &body); if (ii != 0) { _debug("Cannot get body\n"); - return -1; + returnValue = -1; + break; } // Analyse message body - str = new string(body->body); - pos = str->find (VOICE_MSG); + if (!body || !body->body) { + returnValue = -1; + break; + } + std::string str(body->body); + pos = str.find(VOICE_MSG); if (pos == string::npos) { // If the string is not found - delete str; - return -1; + returnValue = -1; + break; } - pos_slash = str->find ("/"); - nb_msg = str->substr(pos + LENGTH_VOICE_MSG, + pos_slash = str.find ("/"); + nb_msg = str.substr(pos + LENGTH_VOICE_MSG, pos_slash - (pos + LENGTH_VOICE_MSG)); // Set the number of voice-message @@ -862,18 +871,18 @@ SipVoIPLink::getEvent (void) // Stop notification when there is 0 voice message Manager::instance().stopVoiceMessageNotification(); } - delete str; } break; default: //Manager::instance().displayErrorText(event->type, "getEvent:default"); - return -1; + returnValue = -1; break; } + _debug("End of GetEvent : %d / %d\n", event->type, returnValue); eXosip_event_free(event); - - return 0; + + return returnValue; } int @@ -934,14 +943,15 @@ SipVoIPLink::newIncomingCall (short callid) void SipVoIPLink::deleteSipCall (short callid) { - unsigned int i = 0; - while (i < _sipcallVector.size()) { - if (_sipcallVector.at(i)->getId() == callid) { - _sipcallVector.erase(_sipcallVector.begin()+i); + std::vector< SipCall * >::iterator iter = _sipcallVector.begin(); + + while(iter != _sipcallVector.end()) { + if ((*iter)->getId() == callid) { + delete *iter; + _sipcallVector.erase(iter); return; - } else { - i++; } + iter++; } } @@ -1172,7 +1182,7 @@ SipVoIPLink::getLocalIp (void) { int ret = 0; char* myIPAddress = new char[65]; - ret = eXosip_guess_localip (2, myIPAddress, 64); + ret = eXosip_guess_localip (AF_INET, myIPAddress, 64); setLocalIpAddress(std::string(myIPAddress)); delete [] myIPAddress; return ret; @@ -1211,15 +1221,17 @@ SipVoIPLink::setAuthentication (void) } pass = manager.getConfigString(SIGNALISATION, PASSWORD); if (pass.empty()) { - manager.error()->errorName(PASSWD_FIELD_EMPTY); + manager.error()->errorName(PASSWD_FIELD_EMPTY); return -1; } - + int returnValue = 0; + eXosip_lock(); if (eXosip_add_authentication_info(login.data(), login.data(), pass.data(), NULL, NULL) != 0) { - return -1; + returnValue = -1; } - return 0; + eXosip_unlock(); + return returnValue; } string @@ -1245,8 +1257,8 @@ int SipVoIPLink::startCall (short id, const string& from, const string& to, const string& subject, const string& route) { - SipCall *call = getSipCall(id); - if ( call == NULL) { + SipCall *sipcall = getSipCall(id); + if ( sipcall == NULL) { return -1; // error, we can't find the sipcall } osip_message_t *invite; @@ -1276,8 +1288,8 @@ SipVoIPLink::startCall (short id, const string& from, const string& to, } // Set local audio port for sipcall(id) - call->setLocalAudioPort(_localPort); - + sipcall->setLocalAudioPort(_localPort); + sipcall->setLocalIp(getLocalIpAddress()); i = eXosip_call_build_initial_invite (&invite, (char*)to.data(), (char*)from.data(), @@ -1339,7 +1351,6 @@ SipVoIPLink::startCall (short id, const string& from, const string& to, "%s", localip, localip, port, media_audio, rtpmap_attr); // media_audio should be one, two or three numbers? - _debug("%s %d", tmp, strlen(tmp)); osip_message_set_body (invite, tmp, strlen (tmp)); osip_message_set_content_type (invite, "application/sdp"); } @@ -1350,7 +1361,7 @@ SipVoIPLink::startCall (short id, const string& from, const string& to, int cid = eXosip_call_send_initial_invite (invite); // Keep the cid in case of cancelling - call->setCid(cid); + sipcall->setCid(cid); if (cid <= 0) { eXosip_unlock(); diff --git a/src/user_cfg.h b/src/user_cfg.h index 7b6fff2dbb..8c7dffb329 100644 --- a/src/user_cfg.h +++ b/src/user_cfg.h @@ -56,8 +56,6 @@ #define CODEC4 "Codecs.codec4" #define CODEC5 "Codecs.codec5" #define RING_CHOICE "Rings.ringChoice" -#define LOCAL_IP "Local.IP" -#define LOCAL_IP_DEFAULT "127.0.0.1" // speakers and volume 0 to 100 -- GitLab