From dd5cc2be9d8e1e42cc2ffc419b077a0c17f7d81c Mon Sep 17 00:00:00 2001 From: jpbl <jpbl> Date: Wed, 13 Jul 2005 21:54:53 +0000 Subject: [PATCH] added some missing files --- src/audio/audiodevice.h | 31 ++ src/managerimpl.cpp | 864 ++++++++++++++++++++++++++++++++++++++++ src/managerimpl.h | 300 ++++++++++++++ 3 files changed, 1195 insertions(+) create mode 100644 src/audio/audiodevice.h create mode 100644 src/managerimpl.cpp create mode 100644 src/managerimpl.h diff --git a/src/audio/audiodevice.h b/src/audio/audiodevice.h new file mode 100644 index 0000000000..2b040a45f7 --- /dev/null +++ b/src/audio/audiodevice.h @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@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 _AUDIO_DEVICE_H +#define _AUDIO_DEVICE_H + +struct AudioDevice +{ + const char *hostApiName; + const char *deviceName; +}; + + +#endif diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp new file mode 100644 index 0000000000..d3ce37b098 --- /dev/null +++ b/src/managerimpl.cpp @@ -0,0 +1,864 @@ +/** + * 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; + +ManagerImpl::ManagerImpl (void) +{ + // initialize random generator + srand (time(NULL)); + + // Init private variables + _callVector = new CallVector(); + _voIPLinkVector = new VoIPLinkVector(); + _error = new Error(); + _tone = new ToneGenerator(); + + + _nCalls = 0; + _nCodecs = 0; + _currentCallId = 0; + _startTime = 0; + _endTime = 0; + _path = ""; + _zonetone = false; + _congestion = false; + _ringtone = false; + _ringback = false; + _exist = 0; + _loaded = false; + +} + +ManagerImpl::~ManagerImpl (void) +{ + delete _callVector; + delete _voIPLinkVector; + delete _error; + delete _tone; + delete _codecDescVector; + delete _audiodriverPA; +} + +void +ManagerImpl::init (void) +{ + // Set a sip voip link by default + _voIPLinkVector->push_back(new SipVoIPLink(DFT_VOIP_LINK)); + + initConfigFile(); + _exist = createSettingsPath(); + if (_exist == 0) { + _debug("Cannot create config file in your home directory\n"); + } + 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 +ManagerImpl::setGui (GuiFramework* gui) +{ + _gui = gui; +} + +ToneGenerator* +ManagerImpl::getTonegenerator (void) +{ + return _tone; +} + +Error* +ManagerImpl::error (void) +{ + return _error; +} + +AudioLayer* +ManagerImpl::getAudioDriver(void) +{ + return _audiodriverPA; +} + +unsigned int +ManagerImpl::getNumberOfCalls (void) +{ + return _nCalls; +} + +void +ManagerImpl::setNumberOfCalls (unsigned int nCalls) +{ + _nCalls = nCalls; +} + +short +ManagerImpl::getCurrentCallId (void) +{ + return _currentCallId; +} + +void +ManagerImpl::setCurrentCallId (short currentCallId) +{ + _currentCallId = currentCallId; +} + +CallVector* +ManagerImpl::getCallVector (void) +{ + return _callVector; +} + +Call* +ManagerImpl::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 +ManagerImpl::getNumberOfCodecs (void) +{ + return _nCodecs; +} + +void +ManagerImpl::setNumberOfCodecs (unsigned int nb_codec) +{ + _nCodecs = nb_codec; +} + +VoIPLinkVector* +ManagerImpl::getVoIPLinkVector (void) +{ + return _voIPLinkVector; +} + +CodecDescriptorVector* +ManagerImpl::getCodecDescVector (void) +{ + return _codecDescVector; +} + +void +ManagerImpl::pushBackNewCall (short id, enum CallType type) +{ + Call* call = new Call(id, type, _voIPLinkVector->at(DFT_VOIP_LINK)); + // Set the wanted voip-link (first of the list) + _callVector->push_back(call); +} + +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++; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Management of events' IP-phone user +/////////////////////////////////////////////////////////////////////////////// +int +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::muteOn (short id) +{ + Call* call; + call = getCall(id); + if (call == NULL) + return; + call->setStatus(string(MUTE_ON_STATUS)); + call->setState(MuteOn); +} + +void +ManagerImpl::muteOff (short id) +{ + Call* call; + call = getCall(id); + if (call == NULL) + return; + call->setStatus(string(CONNECTED_STATUS)); + call->setState(MuteOff); +} + +int +ManagerImpl::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 +ManagerImpl::saveConfig (void) +{ + return (Config::tree()->saveToFile(_path.data()) ? 1 : 0); +} + +int +ManagerImpl::registerVoIPLink (void) +{ + if (_voIPLinkVector->at(DFT_VOIP_LINK)->setRegister() == 0) { + return 1; + } else { + return 0; + } +} + +int +ManagerImpl::quitApplication (void) +{ + // Quit VoIP-link library + _voIPLinkVector->at(DFT_VOIP_LINK)->quit(); + if (saveConfig()) { + return 1; + } else { + return 0; + } + Config::deleteTree(); +} + +int +ManagerImpl::sendTextMessage (short , const string& ) +{ + return 1; +} + +int +ManagerImpl::accessToDirectory (void) +{ + return 1; +} + +int +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::displayTextMessage (short id, const string& message) +{ + _gui->displayTextMessage(id, message); +} + +void +ManagerImpl::displayErrorText (const string& message) +{ + _gui->displayErrorText(message); +} + +void +ManagerImpl::displayError (const string& error) +{ + _gui->displayStatus(error); +} + +void +ManagerImpl::displayStatus (const string& status) +{ + _gui->displayStatus(status); +} + +int +ManagerImpl::selectedCall (void) +{ + return _gui->selectedCall(); +} + +bool +ManagerImpl::isCurrentId (short id) +{ + return _gui->isCurrentId(id); +} + +void +ManagerImpl::congestion (bool var) { + if (isDriverLoaded()) { + if (_congestion != var) { + _congestion = var; + } + _zonetone = var; + _tone->toneHandle(ZT_TONE_CONGESTION); + } else { + _error->errorName(OPEN_FAILED_DEVICE); + } +} + +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); + } +} + +void +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()); + } + + 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 +ManagerImpl::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 +ManagerImpl::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"); + } +} + +AudioDevice +ManagerImpl::deviceList (int index) +{ + AudioDevice deviceParam; + deviceParam.hostApiName = + portaudio::System::instance().deviceByIndex(index).hostApi().name(); + deviceParam.deviceName = + portaudio::System::instance().deviceByIndex(index).name(); + return deviceParam; +} + +int +ManagerImpl::deviceCount (void) +{ + int numDevices = 0; + + portaudio::AutoSystem autoSys; + portaudio::System &sys = portaudio::System::instance(); + numDevices = sys.deviceCount(); + return numDevices; +} + +bool +ManagerImpl::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 +ManagerImpl::useStun (void) { + if (get_config_fields_int(SIGNALISATION, USE_STUN) == YES) { + return true; + } else { + return false; + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Private functions +/////////////////////////////////////////////////////////////////////////////// + +short +ManagerImpl::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 +ManagerImpl::callVectorSize (void) +{ + return _callVector->size(); +} + +int +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::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 +ManagerImpl::selectAudioDriver (void) +{ + +#if defined(AUDIO_PORTAUDIO) + _audiodriverPA = new AudioLayer(); + _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/managerimpl.h b/src/managerimpl.h new file mode 100644 index 0000000000..cc515b67e3 --- /dev/null +++ b/src/managerimpl.h @@ -0,0 +1,300 @@ +/** + * 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 __MANAGER_H__ +#define __MANAGER_H__ + +#include <cc++/thread.h> + +#include <string> +#include <vector> + +#include "../stund/stun.h" +#include "call.h" +#include "audio/audiodevice.h" + +using namespace std; +using namespace ost; + +class AudioLayer; +class CodecDescriptor; +class Error; +class GuiFramework; +class ToneGenerator; +class VoIPLink; + +#define NOTIFICATION_LEN 250 +// Status +#define CONNECTED_STATUS "Connected" +#define LOGGED_IN_STATUS "Logged in" +#define RINGING_STATUS "Ringing" +#define TRYING_STATUS "Trying ..." +#define HUNGUP_STATUS "Hung up" +#define ONHOLD_STATUS "On hold ..." +#define TRANSFER_STATUS "Transfer to:" +#define MUTE_ON_STATUS "Mute on" +#define ENTER_NUMBER_STATUS "Enter Phone Number:" + +/* + * Define a type for a list of call + */ +typedef vector<Call*, allocator<Call*> > CallVector; + +/* + * Define a type for a list of VoIPLink + */ +typedef vector<VoIPLink*, allocator<VoIPLink*> > VoIPLinkVector; + +/* + * Define a type for a list of CodecDescriptor + */ +typedef vector<CodecDescriptor*, allocator<CodecDescriptor*> > CodecDescriptorVector; + +struct device_t{ + const char* hostApiName; + const char* deviceName; +}; + +class ManagerImpl { +public: + ManagerImpl (void); + ~ManagerImpl (void); + + void init (void); + void setGui (GuiFramework* gui); + ToneGenerator* getTonegenerator(void); + Error* error(void); + AudioLayer* getAudioDriver(void); + + // Accessor to number of calls + unsigned int getNumberOfCalls (void); + // Modifior of number of calls + void setNumberOfCalls (unsigned int nCalls); + + // Accessor to current call id + short getCurrentCallId (void); + // Modifior of current call id + void setCurrentCallId (short currentCallId); + + // Accessor to the Call vector + CallVector* getCallVector (void); + // Accessor to the Call with the id 'id' + Call* getCall (short id); + + unsigned int getNumberOfCodecs (void); + void setNumberOfCodecs (unsigned int nb_codec); + + VoIPLinkVector* getVoIPLinkVector (void); + + CodecDescriptorVector* getCodecDescVector(void); + + inline bool getZonetone (void) { return _zonetone; } + inline void setZonetone (bool b) { _zonetone = b; } + + /* + * Attribute a new random id for a new call + * and check if it's already attributed to existing calls. + * If not exists, returns 'id' otherwise return 0 + */ + short generateNewCallId (void); + + /* + * Add a new call at the end of the CallVector with identifiant 'id' + */ + void pushBackNewCall (short id, enum CallType type); + + /* + * Erase the Call(id) from the CallVector + */ + void deleteCall (short id); + + /* + * Functions which occur with a user's action + */ + int outgoingCall (const string& to); + int hangupCall (short id); + int cancelCall (short id); + int answerCall (short id); + int onHoldCall (short id); + int offHoldCall (short id); + int transferCall (short id, const string& to); + void muteOn (short id); + void muteOff (short id); + int refuseCall (short id); + + int saveConfig (void); + int registerVoIPLink (void); + int quitApplication (void); + int sendTextMessage (short id, const string& message); + int accessToDirectory (void); + + /** + * Handle choice of the DTMF-send-way + * + * @param id: callid of the line. + * @param code: pressed key. + */ + int sendDtmf (short id, char code); + + + int incomingCall (short id); + void peerAnsweredCall (short id); + int peerRingingCall (short id); + int peerHungupCall (short id); + void displayTextMessage (short id, const string& message); + void displayErrorText (const string& message); + void displayError (const string& error); + void displayStatus (const string& status); + int selectedCall (void); + bool isCurrentId (short id); + + /* + * Handle audio sounds heard by a caller while they wait for their + * connection to a called party to be completed. + */ + void ringback (bool var); + + /* + * Handle played music when an incoming call occurs + */ + void ringtone (bool var); + + void congestion (bool var); + + /* + * Notification of incoming call when you are already busy + */ + void notificationIncomingCall (void); + + /* + * Get information about firewall + * @param stunSvrAddr: stun server + */ + void getStunInfo (StunAddress4& stunSvrAddr); + bool useStun (void); + + inline bool getbCongestion (void) { return _congestion; } + inline bool getbRingback (void) { return _ringback; } + inline bool getbRingtone (void) { return _ringtone; } + + 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_vol; } + + inline int getFirewallPort (void) { return _firewallPort; } + inline void setFirewallPort (int port) { _firewallPort = port; } + inline string getFirewallAddress (void) { return _firewallAddr; } + + inline bool isDriverLoaded (void) { return _loaded; } + inline void loaded (bool l) { _loaded = l; } + + /* + * Functions about audio device + */ + AudioDevice deviceList (int); + int deviceCount (void); + bool defaultDevice (int); + +private: + + /* + * Returns the number of calls in the vector + */ + unsigned int callVectorSize (void); + + /** + * Create .PROGNAME directory in home user and create + * configuration tree from the settings file if this file exists. + * + * @return 0 if creating file failed + * 1 if config-file exists + * 2 if file doesn't exist yet. + */ + int createSettingsPath (void); + + /* + * Init default values for the different fields + */ + void initConfigFile (void); + + void initAudioCodec(void); + void selectAudioDriver (void); + +///////////////////// +// Private variables +///////////////////// + ToneGenerator* _tone; + Error* _error; + GuiFramework* _gui; + AudioLayer* _audiodriverPA; + + /* + * Vector of VoIPLink + */ + VoIPLinkVector* _voIPLinkVector; + + /* + * Vector of calls + */ + CallVector* _callVector; + + /* + * Vector of CodecDescriptor + */ + CodecDescriptorVector* _codecDescVector; + + /* + * Mutex to protect access to code section + */ + Mutex _mutex; + + unsigned int _nCalls; + short _currentCallId; + + /* + * For the call timer + */ + unsigned int _startTime; + unsigned int _endTime; + + /* Path of the ConfigFile + */ + string _path; + int _exist; + + unsigned int _nCodecs; + bool _zonetone; + bool _congestion; + bool _ringback; + bool _ringtone; + + // To handle volume control + int _spkr_volume; + int _mic_volume; + + // To handle firewall + int _firewallPort; + string _firewallAddr; + + // Variables used in exception + bool _loaded; +}; + +#endif // __MANAGER_H__ -- GitLab