Skip to content
Snippets Groups Projects
Commit 2befedfe authored by yanmorin's avatar yanmorin
Browse files

New Architecture (see doc/sflphone-server2.xmi)
parent bcc70ba8
No related branches found
No related tags found
No related merge requests found
...@@ -42,19 +42,6 @@ GUIServerImpl::exec() { ...@@ -42,19 +42,6 @@ GUIServerImpl::exec() {
} }
bool
GUIServerImpl::outgoingCall (const std::string& seq, const std::string& callid, const std::string& to)
{
short serverCallId = GuiFramework::outgoingCall(to);
if ( serverCallId ) {
SubCall subcall(seq, callid);
insertSubCall(serverCallId, subcall);
return true;
} else {
return false;
}
}
/** /**
* SubCall operations * SubCall operations
* insert * insert
...@@ -95,17 +82,100 @@ GUIServerImpl::getIdFromCallId(const std::string& callId) ...@@ -95,17 +82,100 @@ GUIServerImpl::getIdFromCallId(const std::string& callId)
throw std::runtime_error("No match for this CallId"); throw std::runtime_error("No match for this CallId");
} }
void bool
GUIServerImpl::hangup(const std::string& callId) { GUIServerImpl::outgoingCall (const std::string& seq, const std::string& callid, const std::string& to)
{
short serverCallId = GuiFramework::outgoingCall(to);
if ( serverCallId ) {
SubCall subcall(seq, callid);
insertSubCall(serverCallId, subcall);
return true;
} else {
return false;
}
}
bool
GUIServerImpl::answerCall(const std::string& callId)
{
try {
short id = getIdFromCallId(callId);
if (GuiFramework::answerCall(id)) {
return true;
}
} catch(...) {
return false;
}
return false;
}
bool
GUIServerImpl::refuseCall(const std::string& callId)
{
try { try {
short id = getIdFromCallId(callId); short id = getIdFromCallId(callId);
// There was a problem when hanging up... if (GuiFramework::refuseCall(id)) {
if (!GuiFramework::hangupCall(id)) { return true;
throw std::runtime_error("Error when hangup");
} }
} catch(...) { } catch(...) {
throw; return false;
} }
return false;
}
bool
GUIServerImpl::holdCall(const std::string& callId)
{
try {
short id = getIdFromCallId(callId);
if (GuiFramework::onHoldCall(id)) {
return true;
}
} catch(...) {
return false;
}
return false;
}
bool
GUIServerImpl::unholdCall(const std::string& callId)
{
try {
short id = getIdFromCallId(callId);
if (GuiFramework::offHoldCall(id)) {
return true;
}
} catch(...) {
return false;
}
return false;
}
bool
GUIServerImpl::hangupCall(const std::string& callId)
{
try {
short id = getIdFromCallId(callId);
if (GuiFramework::hangupCall(id)) {
return true;
}
} catch(...) {
return false;
}
return false;
}
bool
GUIServerImpl::dtmfCall(const std::string& callId, const std::string& dtmfKey)
{
try {
short id = getIdFromCallId(callId);
char code = dtmfKey[0];
return GuiFramework::sendDtmf(id, code);
} catch(...) {
return false;
}
return false;
} }
int int
...@@ -140,6 +210,16 @@ GUIServerImpl::peerRingingCall (short id) ...@@ -140,6 +210,16 @@ GUIServerImpl::peerRingingCall (short id)
int int
GUIServerImpl::peerHungupCall (short id) GUIServerImpl::peerHungupCall (short id)
{ {
CallMap::iterator iter = _callMap.find(id);
if ( iter != _callMap.end() ) {
std::ostringstream responseMessage;
responseMessage << iter->second.callId() << " hangup";
_requestManager.sendResponse(ResponseMessage("250", "seq0", responseMessage.str()));
// remove this call...
_callMap.erase(id);
}
return 0; return 0;
} }
......
...@@ -61,8 +61,13 @@ public: ...@@ -61,8 +61,13 @@ public:
bool outgoingCall (const std::string& seq, bool outgoingCall (const std::string& seq,
const std::string& callid, const std::string& callid,
const std::string& to); const std::string& to);
bool answerCall(const std::string& callId);
bool refuseCall(const std::string& callId);
bool holdCall(const std::string& callId);
bool unholdCall(const std::string& callId);
bool hangupCall(const std::string& callId);
bool dtmfCall(const std::string& callId, const std::string& dtmfKey);
void hangup(const std::string& callId);
void quit() {_shouldQuit=true;} void quit() {_shouldQuit=true;}
private: private:
......
...@@ -26,33 +26,44 @@ RequestCall::execute() ...@@ -26,33 +26,44 @@ RequestCall::execute()
{ {
if ( GUIServer::instance().outgoingCall(_sequenceId, _callId, _destination) ) { if ( GUIServer::instance().outgoingCall(_sequenceId, _callId, _destination) ) {
return message("150", "Trying"); return message("150", "Trying");
} else {
return message("500","Server Error");
} }
return message("500","Server Error");
} }
ResponseMessage ResponseMessage
RequestAnswer::execute() RequestAnswer::execute()
{ {
return message("200","TODO"); if ( GUIServer::instance().answerCall(_callId) ) {
return message("200", "OK");
}
return message("500","Server Error");
} }
ResponseMessage ResponseMessage
RequestRefuse::execute() RequestRefuse::execute()
{ {
return message("200","TODO"); if ( GUIServer::instance().refuseCall(_callId) ) {
return message("200", "OK");
}
return message("500","Server Error");
} }
ResponseMessage ResponseMessage
RequestHold::execute() RequestHold::execute()
{ {
return message("200","TODO"); if ( GUIServer::instance().holdCall(_callId) ) {
return message("200", "OK");
}
return message("500","Server Error");
} }
ResponseMessage ResponseMessage
RequestUnhold::execute() RequestUnhold::execute()
{ {
return message("200","TODO"); if ( GUIServer::instance().unholdCall(_callId) ) {
return message("200", "OK");
}
return message("500","Server Error");
} }
ResponseMessage ResponseMessage
...@@ -64,12 +75,37 @@ RequestTransfer::execute() ...@@ -64,12 +75,37 @@ RequestTransfer::execute()
ResponseMessage ResponseMessage
RequestHangup::execute() RequestHangup::execute()
{ {
try { if ( GUIServer::instance().hangupCall(_callId) ) {
GUIServer::instance().hangup(_callId);
return message("200", "OK"); return message("200", "OK");
} catch (...) { }
return message("500", "Hangup Error"); return message("500", "Hangup Error");
} }
RequestDTMF::RequestDTMF(const std::string &sequenceId,
const TokenList& argList) : RequestGlobalCall(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
RequestDTMF::execute()
{
if ( GUIServer::instance().dtmfCall(_callId, _dtmfKey) ) {
return message("200", "OK");
}
return message("500", "DTMF Error");
} }
......
...@@ -140,6 +140,17 @@ public: ...@@ -140,6 +140,17 @@ public:
ResponseMessage execute(); ResponseMessage execute();
}; };
class RequestDTMF : public RequestGlobalCall {
public:
RequestDTMF(const std::string &sequenceId,
const TokenList& argList);
ResponseMessage execute();
private:
std::string _dtmfKey;
};
class RequestGlobal : public Request class RequestGlobal : public Request
{ {
public: public:
......
...@@ -92,6 +92,7 @@ RequestFactory::registerAll() { ...@@ -92,6 +92,7 @@ RequestFactory::registerAll() {
registerRequest<RequestHold> ("hold"); registerRequest<RequestHold> ("hold");
registerRequest<RequestUnhold> ("unhold"); registerRequest<RequestUnhold> ("unhold");
registerRequest<RequestHangup> ("hangup"); registerRequest<RequestHangup> ("hangup");
registerRequest<RequestDTMF> ("dtmf");
registerRequest<RequestTransfer> ("transfer"); registerRequest<RequestTransfer> ("transfer");
registerRequest<RequestMute> ("mute"); registerRequest<RequestMute> ("mute");
registerRequest<RequestUnmute> ("unmute"); registerRequest<RequestUnmute> ("unmute");
......
...@@ -30,6 +30,7 @@ RequestManager::RequestManager() : _sessionIO(0) ...@@ -30,6 +30,7 @@ RequestManager::RequestManager() : _sessionIO(0)
RequestManager::~RequestManager() RequestManager::~RequestManager()
{ {
delete _sessionIO;
flushWaitingRequest(); flushWaitingRequest();
} }
...@@ -37,29 +38,25 @@ int ...@@ -37,29 +38,25 @@ int
RequestManager::exec() RequestManager::exec()
{ {
try { try {
ost::InetAddress addr("127.0.0.1"); // waiting for a new connection
std::cout << "waiting for a new connection..." << std::endl;
//Creating a listening socket // TCPSessionIO start a thread for the stream socket
ost::TCPSocket aServer(addr, 3999); _sessionIO = new TCPSessionIO();
// wait for the first message
std::cout << "accepting connection..." << std::endl;
ResponseMessage outputResponse; // TCPStream output line ResponseMessage outputResponse; // TCPStream output line
std::string input; std::string input;
std::string output; std::string output;
Request *request; Request *request;
while (std::cin.good()) { _sessionIO->init();
// waiting for a new connection
std::cout << "waiting for a new connection..." << std::endl;
//I'm accepting an incomming connection
_sessionIO = new TCPSessionIO(aServer);
_sessionIO->start();
// wait for the first message
std::cout << "accepting connection..." << std::endl;
while(_sessionIO->good()) { // std::cin.good() is only there to close the server when
// we do a CTRL+D
while(std::cin.good()) {
if (_sessionIO->receive(input)) { if (_sessionIO->receive(input)) {
...@@ -72,8 +69,8 @@ RequestManager::exec() ...@@ -72,8 +69,8 @@ RequestManager::exec()
} // end pop } // end pop
} // end streaming } // end streaming
delete _sessionIO;
} // end server side : ctrl + d _sessionIO = 0;
} catch(ost::Socket *e) { } catch(ost::Socket *e) {
std::cerr << e->getErrorString() << std::endl; std::cerr << e->getErrorString() << std::endl;
...@@ -126,8 +123,6 @@ void ...@@ -126,8 +123,6 @@ void
RequestManager::sendResponse(const ResponseMessage& response) { RequestManager::sendResponse(const ResponseMessage& response) {
if (_sessionIO) { if (_sessionIO) {
_sessionIO->send(response.toString()); _sessionIO->send(response.toString());
} else {
std::cerr << "RequestManager::sendResponse: no initialize sessionIO" << response.toString() << std::endl;
} }
// remove the request from the waiting requests list // remove the request from the waiting requests list
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <cc++/thread.h> #include <cc++/thread.h>
#include "tcpsessionio.h" #include "sessionio.h"
#include "requestfactory.h" #include "requestfactory.h"
#include "responsemessage.h" #include "responsemessage.h"
...@@ -42,7 +42,7 @@ private: ...@@ -42,7 +42,7 @@ private:
void handleExecutedRequest(Request * const request, const ResponseMessage& response); void handleExecutedRequest(Request * const request, const ResponseMessage& response);
RequestFactory _factory; RequestFactory _factory;
TCPSessionIO* _sessionIO; SessionIO* _sessionIO;
// waiting requests // waiting requests
ost::Mutex _waitingRequestsMutex; ost::Mutex _waitingRequestsMutex;
......
/**
* 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 "sessionio.h"
SessionIO::SessionIO()
{
}
SessionIO::~SessionIO()
{
}
/**
* 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 SESSIONIO_H
#define SESSIONIO_H
#include <string>
/**
Session IO Interface to send and receive requests
Could be over network or locally
@author Yan Morin
*/
class SessionIO {
public:
SessionIO();
virtual ~SessionIO();
virtual void send(const std::string& response) = 0;
virtual bool receive(std::string& request) = 0;
virtual bool good() = 0;
virtual void init() = 0;
};
#endif
/** //
* Copyright (C) 2005 Savoir-Faire Linux inc. // C++ Implementation: tcpsessionio
* Author: Yan Morin <yan.morin@savoirfairelinux.com> //
* // Description:
* 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 // Author: Yan Morin <yan.morin@savoirfairelinux.com>, (C) 2005
* (at your option) any later version. //
* // Copyright: See COPYING file that comes with this distribution
* 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" #include "tcpsessionio.h"
#include "../../global.h"
void
TCPSessionIO::run() {
std::string output;
std::string input;
while(!testCancel() && good()) { const int TCPSessionIO::PORT = 3999;
if (isPending(ost::TCPSocket::pendingInput, 10)) { const char * const TCPSessionIO::IP = "127.0.0.1";
std::getline(*this, input);
_inputPool.push(input); TCPSessionIO::TCPSessionIO() : SessionIO()
{
_clientStream = 0;
ost::InetAddress addr(IP);
//Creating a listening socket
_serverSocket = new ost::TCPSocket(addr, PORT);
} }
if (_outputPool.pop(output, 10LU)) {
*this << output << std::endl;
TCPSessionIO::~TCPSessionIO()
{
delete _clientStream;
delete _serverSocket;
} }
bool
TCPSessionIO::good()
{
if (_clientStream) { // just in case
_debug("_clientStream->good() == %d\n", _clientStream->good());
return _clientStream->good();
} }
_debug("_clientStream doesn't exists yet...");
return false;
} }
void void
TCPSessionIO::send(const std::string& response) TCPSessionIO::send(const std::string& response)
{ {
_outputPool.push(response); if (_clientStream) { // just in case
_clientStream->send(response);
}
} }
bool bool
TCPSessionIO::receive(std::string& request) TCPSessionIO::receive(std::string& request)
{ {
if ( _inputPool.pop(request, 10LU) ) { if (_clientStream) { // just in case
return true; return _clientStream->receive(request);
} }
return false; return false;
} }
void
TCPSessionIO::init() {
// this is strange to create a waiting client here...
_clientStream = new TCPStreamPool(*_serverSocket);
_clientStream->start();
}
/** //
* Copyright (C) 2005 Savoir-Faire Linux inc. // C++ Interface: tcpsessionio
* Author: Yan Morin <yan.morin@savoirfairelinux.com> //
* // Description:
* 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 // Author: Yan Morin <yan.morin@savoirfairelinux.com>, (C) 2005
* (at your option) any later version. //
* // Copyright: See COPYING file that comes with this distribution
* 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 #ifndef TCPSESSIONIO_H
#define TCPSESSIONIO_H #define TCPSESSIONIO_H
#include <string>
#include <cc++/socket.h> #include <cc++/socket.h>
#include "sessionio.h"
#include "ObjectPool.hpp" #include "tcpstreampool.h"
/** /**
* Utilisation: @author Yan Morin
* TCPSessionIO session = TCPSessionIO(aServer);
* std::string response = "hello";
* std::string request;
* session.start();
* session.send(response);
* while(session.receive(request)) {
* std::cout << request << std::endl;
* }
* @author Yan Morin
*/ */
class TCPSessionIO : public ost::TCPSession class TCPSessionIO : public SessionIO
{ {
public: public:
TCPSessionIO(ost::TCPSocket& server) : ost::TCPSession(server) {} TCPSessionIO();
~TCPSessionIO();
void run();
void send(const std::string& response); void send(const std::string& response);
bool receive(std::string& request); bool receive(std::string& request);
bool good();
void init();
private: private:
ObjectPool<std::string> _outputPool; ost::TCPSocket* _serverSocket;
ObjectPool<std::string> _inputPool; TCPStreamPool* _clientStream;
static const int PORT;
static const char * const IP;
}; };
#endif #endif
/**
* 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 "tcpstreampool.h"
void
TCPStreamPool::run() {
std::string output;
std::string input;
while(!testCancel() && good()) {
if (isPending(ost::TCPSocket::pendingInput, 2)) {
std::getline(*this, input);
_inputPool.push(input);
}
if (_outputPool.pop(output, 2LU)) {
*this << output << std::endl;
}
}
}
void
TCPStreamPool::send(const std::string& response)
{
_outputPool.push(response);
}
bool
TCPStreamPool::receive(std::string& request)
{
if ( _inputPool.pop(request, 2LU) ) {
return true;
}
return false;
}
/**
* 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 TCPSTREAMPOOL_H
#define TCPSTREAMPOOL_H
#include <string>
#include <cc++/socket.h>
#include "ObjectPool.hpp"
/**
* Utilisation:
* TCPSessionIO session = TCPStreamPool(aServer);
* std::string response = "hello";
* std::string request;
* session.start();
* session.send(response);
* while(session.receive(request)) {
* std::cout << request << std::endl;
* }
* @author Yan Morin
*/
class TCPStreamPool : public ost::TCPSession
{
public:
TCPStreamPool(ost::TCPSocket& server) : ost::TCPSession(server) {}
void run();
void send(const std::string& response);
bool receive(std::string& request);
private:
ObjectPool<std::string> _outputPool;
ObjectPool<std::string> _inputPool;
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment