From c5100adf741e2ca6ce8eea25002cddf2787674df Mon Sep 17 00:00:00 2001 From: yanmorin <yanmorin> Date: Tue, 27 Sep 2005 18:44:37 +0000 Subject: [PATCH] Add config request classes (not yet implemented) Add playtone/playdtmf Only playdtmf work right now --- src/audio/dtmf.cpp | 57 ++++++++++++---------- src/gui/guiframework.cpp | 12 +++++ src/gui/guiframework.h | 2 + src/gui/server/Makefile.am | 8 ++-- src/gui/server/request.cpp | 35 ++++++++++++++ src/gui/server/request.h | 20 ++++++++ src/gui/server/requestconfig.cpp | 77 +++++++++++++++++++++++++++++ src/gui/server/requestconfig.h | 80 +++++++++++++++++++++++++++++++ src/gui/server/requestfactory.cpp | 41 +++++++++++----- src/managerimpl.cpp | 58 ++++++++++++++++++++++ src/managerimpl.h | 2 + 11 files changed, 349 insertions(+), 43 deletions(-) create mode 100644 src/gui/server/requestconfig.cpp create mode 100644 src/gui/server/requestconfig.h diff --git a/src/audio/dtmf.cpp b/src/audio/dtmf.cpp index eff5e60747..0ef3861974 100644 --- a/src/audio/dtmf.cpp +++ b/src/audio/dtmf.cpp @@ -39,30 +39,35 @@ bool DTMF::generateDTMF (int16* buffer, size_t n) { if (!buffer) return false; - if (currentTone != 0) { - // Currently generating a DTMF tone - if (currentTone == newTone) { - // Continue generating the same tone - dtmf.getNextSamples(buffer, n); - return true; - } else if (newTone != 0) { - // New tone requested - dtmf.getSamples(buffer, n, newTone); - currentTone = newTone; - return true; - } else { - // Stop requested - currentTone = newTone; - return false; - } - } else { - // Not generating any DTMF tone - if (newTone) { - // Requested to generate a DTMF tone - dtmf.getSamples(buffer, n, newTone); - currentTone = newTone; - return true; - } - return false; - } + try { + if (currentTone != 0) { + // Currently generating a DTMF tone + if (currentTone == newTone) { + // Continue generating the same tone + dtmf.getNextSamples(buffer, n); + return true; + } else if (newTone != 0) { + // New tone requested + dtmf.getSamples(buffer, n, newTone); + currentTone = newTone; + return true; + } else { + // Stop requested + currentTone = newTone; + return false; + } + } else { + // Not generating any DTMF tone + if (newTone) { + // Requested to generate a DTMF tone + dtmf.getSamples(buffer, n, newTone); + currentTone = newTone; + return true; + } + return false; + } + } catch(DTMFException e) { + // invalid key + return false; + } } diff --git a/src/gui/guiframework.cpp b/src/gui/guiframework.cpp index b5baba0aa8..e603ec3e7a 100644 --- a/src/gui/guiframework.cpp +++ b/src/gui/guiframework.cpp @@ -173,6 +173,18 @@ GuiFramework::sendDtmf (short id, char code) return Manager::instance().sendDtmf(id, code); } +bool +GuiFramework::playDtmf (char code) +{ + return Manager::instance().playDtmf(code); +} + +bool +GuiFramework::playTone () +{ + return Manager::instance().playTone(); +} + int GuiFramework::quitApplication (void) { diff --git a/src/gui/guiframework.h b/src/gui/guiframework.h index ac110eacb6..d44cfd08e7 100644 --- a/src/gui/guiframework.h +++ b/src/gui/guiframework.h @@ -69,6 +69,8 @@ public: int sendTextMessage (short id, const std::string& message); int accessToDirectory (void); bool sendDtmf (short id, char code); + bool playDtmf (char code); + bool playTone (); protected: std::string _message; diff --git a/src/gui/server/Makefile.am b/src/gui/server/Makefile.am index 1e58064d9b..0cd86e1fe5 100644 --- a/src/gui/server/Makefile.am +++ b/src/gui/server/Makefile.am @@ -1,8 +1,8 @@ noinst_LTLIBRARIES = libsflphoneguiserver.la libsflphoneguiserver_la_SOURCES = $(BUILT_SOURCES) guiserverimpl.cpp \ - responsemessage.cpp request.cpp requestfactory.cpp argtokenizer.cpp tcpsessionio.cpp \ - requestmanager.cpp sessionio.cpp tcpstreampool.cpp + responsemessage.cpp request.cpp requestfactory.cpp argtokenizer.cpp tcpsessionio.cpp \ + requestmanager.cpp sessionio.cpp tcpstreampool.cpp requestconfig.cpp libsflphoneguiserver_la_CXXFLAGS = -DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" libsflphoneguiserver_la_LIBADD = @@ -10,5 +10,5 @@ libsflphoneguiserver_la_LIBADD = AM_CPPFLAGS = -I$(top_srcdir) $(libccext2_CFLAGS) noinst_HEADERS = responsemessage.h request.h requestfactory.h subcall.h \ - argtokenizer.h tcpsessionio.h requestmanager.h guiserver.h guiserverimpl.h sessionio.h \ - tcpsessionio.h tcpstreampool.h + argtokenizer.h tcpsessionio.h requestmanager.h guiserver.h guiserverimpl.h sessionio.h \ + tcpsessionio.h tcpstreampool.h requestconfig.h diff --git a/src/gui/server/request.cpp b/src/gui/server/request.cpp index 2a7fad5c31..d6ba31265b 100644 --- a/src/gui/server/request.cpp +++ b/src/gui/server/request.cpp @@ -117,6 +117,41 @@ RequestDTMF::execute() return message("500", "DTMF Error"); } +RequestPlayDtmf::RequestPlayDtmf(const std::string &sequenceId, + const TokenList& argList) : RequestGlobal(sequenceId, argList) +{ + + TokenList::iterator iter = _argList.begin(); + + // check for the dtmf key + bool argsAreValid = false; + if (iter != _argList.end() && (*iter).length()==1) { + _dtmfKey = *iter; + _argList.pop_front(); + argsAreValid = true; + } + if (!argsAreValid) { + throw RequestConstructorException(); + } +} + +ResponseMessage +RequestPlayDtmf::execute() +{ + if ( GUIServer::instance().playDtmf(_dtmfKey[0]) ) { + return message("200", "OK"); + } + return message("500", "DTMF Error"); +} + +ResponseMessage +RequestPlayTone::execute() +{ + if ( GUIServer::instance().playTone() ) { + return message("200", "OK"); + } + return message("500", "DTMF Error"); +} ResponseMessage RequestMute::execute() diff --git a/src/gui/server/request.h b/src/gui/server/request.h index 7ab3b5d352..8b72e7d4c0 100644 --- a/src/gui/server/request.h +++ b/src/gui/server/request.h @@ -186,6 +186,26 @@ public: ResponseMessage execute(); }; +class RequestPlayDtmf : public RequestGlobal { +public: + RequestPlayDtmf(const std::string &sequenceId, + const TokenList& argList); + ResponseMessage execute(); +private: + std::string _dtmfKey; +}; + +class RequestPlayTone : public RequestGlobal { +public: + RequestPlayTone(const std::string &sequenceId, + const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + + + + class RequestSyntaxError : public Request { public: diff --git a/src/gui/server/requestconfig.cpp b/src/gui/server/requestconfig.cpp new file mode 100644 index 0000000000..2171066290 --- /dev/null +++ b/src/gui/server/requestconfig.cpp @@ -0,0 +1,77 @@ +/** + * 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 "requestconfig.h" +#include "guiserver.h" +#include "subcall.h" + + +ResponseMessage +RequestZeroconf::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +Request::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestZeroconfEvent::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestCallStatus::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestConfigGetAll::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestConfigGet::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestConfigSet::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestConfigSave::execute() +{ + return message("500","TODO"); +} + +ResponseMessage +RequestList::execute() +{ + return message("500","TODO"); +} diff --git a/src/gui/server/requestconfig.h b/src/gui/server/requestconfig.h new file mode 100644 index 0000000000..f15e2f5b8b --- /dev/null +++ b/src/gui/server/requestconfig.h @@ -0,0 +1,80 @@ +/** + * 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 __REQUESTCONFIG_H__ +#define __REQUESTCONFIG_H__ + +#include "request.h" + + +class RequestZeroconf : public RequestGlobal { +public: + RequestZeroconf(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + +class RequestZeroconfEvent : public RequestGlobal { +public: + RequestZeroconfEvent(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + +class RequestCallStatus : public RequestGlobal { +public: + RequestCallStatus(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + +class RequestConfigGetAll : public RequestGlobal { +public: + RequestConfigGetAll(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + +class RequestConfigGet : public RequestGlobal { +public: + RequestConfigGet(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + +class RequestConfigSet : public RequestGlobal { +public: + RequestConfigSet(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + + +class RequestConfigSave : public RequestGlobal { +public: + RequestConfigSave(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + +class RequestList : public RequestGlobal { +public: + RequestList(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + ResponseMessage execute(); +}; + +#endif // __REQUESTCONFIG_H__ diff --git a/src/gui/server/requestfactory.cpp b/src/gui/server/requestfactory.cpp index a433239506..a388eedd27 100644 --- a/src/gui/server/requestfactory.cpp +++ b/src/gui/server/requestfactory.cpp @@ -21,6 +21,7 @@ #include <stdexcept> #include "request.h" +#include "requestconfig.h" Request * RequestFactory::create(const std::string& requestLine) @@ -85,17 +86,31 @@ RequestFactory::registerRequest(const std::string &requestname) void RequestFactory::registerAll() { registerRequest<RequestSyntaxError> ("syntaxerror"); - registerRequest<RequestCall> ("call"); - registerRequest<RequestAnswer> ("answer"); - registerRequest<RequestRefuse> ("refuse"); - registerRequest<RequestHold> ("hold"); - registerRequest<RequestUnhold> ("unhold"); - registerRequest<RequestHangup> ("hangup"); - registerRequest<RequestHangupAll> ("hangupall"); - registerRequest<RequestDTMF> ("dtmf"); - registerRequest<RequestTransfer> ("transfer"); - registerRequest<RequestMute> ("mute"); - registerRequest<RequestUnmute> ("unmute"); - registerRequest<RequestVersion> ("version"); - registerRequest<RequestQuit> ("quit"); + registerRequest<RequestCall> ("call"); + registerRequest<RequestAnswer> ("answer"); + registerRequest<RequestRefuse> ("refuse"); + registerRequest<RequestHold> ("hold"); + registerRequest<RequestUnhold> ("unhold"); + registerRequest<RequestHangup> ("hangup"); + registerRequest<RequestHangupAll> ("hangupall"); + registerRequest<RequestDTMF> ("senddtmf"); + registerRequest<RequestPlayDtmf> ("playdtmf"); + registerRequest<RequestPlayTone> ("playtone"); + registerRequest<RequestTransfer> ("transfer"); + registerRequest<RequestMute> ("mute"); + registerRequest<RequestUnmute> ("unmute"); + registerRequest<RequestVersion> ("version"); + registerRequest<RequestQuit> ("quit"); + + // request config + registerRequest<RequestZeroconf> ("getzeroconf"); + registerRequest<RequestZeroconfEvent>("getzeroconfevents"); + registerRequest<RequestCallStatus> ("getcallstatus"); + registerRequest<RequestConfigGetAll>("configgetall"); + registerRequest<RequestConfigGet> ("configget"); + registerRequest<RequestConfigSet> ("configset"); + registerRequest<RequestConfigSave> ("configsave"); + registerRequest<RequestList> ("list"); + + } diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 5e4787d6cc..f7bd78090c 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -42,6 +42,7 @@ #include "audio/codecDescriptor.h" #include "audio/ringbuffer.h" #include "audio/tonegenerator.h" +#include "audio/dtmf.h" #include "call.h" #include "configuration.h" #include "configurationtree.h" @@ -555,6 +556,63 @@ ManagerImpl::sendDtmf (short id, char code) break; } } +/** + * @source + */ +bool +ManagerImpl::playDtmf(char code) +{ + int16* _buf = new int16[SIZEBUF]; + bool returnValue = false; + + // Handle dtmf + DTMF key; + key.startTone(code); + if ( key.generateDTMF(_buf, SAMPLING_RATE) ) { + + int k, spkrVolume; + int16* buf_ctrl_vol; + + // Determine dtmf pulse length + int pulselen = get_config_fields_int(SIGNALISATION, PULSE_LENGTH); + int size = pulselen * (OCTETS /1000); + + buf_ctrl_vol = new int16[size*CHANNELS]; + spkrVolume = getSpkrVolume(); + + // Control volume and format mono->stereo + for (int j = 0; j < size; j++) { + k = j*2; + buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = _buf[j] * spkrVolume/100; + } + + AudioLayer *audiolayer = getAudioDriver(); + 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(); + } else { + audiolayer->sleep(pulselen); + } + delete[] buf_ctrl_vol; + returnValue = true; + } + delete[] _buf; + return returnValue; +} + +bool +ManagerImpl::playTone() +{ + return true; +} /////////////////////////////////////////////////////////////////////////////// // Management of event peer IP-phone diff --git a/src/managerimpl.h b/src/managerimpl.h index 4321043d05..6da774357f 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -169,6 +169,8 @@ public: * @param code: pressed key. */ bool sendDtmf (short id, char code); + bool playDtmf (char code); + bool playTone (); int incomingCall (short id); -- GitLab