Skip to content
Snippets Groups Projects
Commit 26ad6d41 authored by yanmorin's avatar yanmorin
Browse files

New files for Server classes
parent b75aa3c3
Branches
Tags
No related merge requests found
/**
* 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 "guiserver.h"
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "responsemessage.h"
// default constructor
GUIServerImpl::GUIServerImpl()
{
_shouldQuit = false;
}
// destructor
GUIServerImpl::~GUIServerImpl()
{
}
int
GUIServerImpl::exec() {
return _requestManager.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
* insert
* remove
*/
void
GUIServerImpl::insertSubCall(short id, SubCall& subCall) {
_callMap[id] = subCall;
}
void
GUIServerImpl::removeSubCall(short id) {
_callMap.erase(id);
}
/**
* Retreive the subcall or send 0
*/
std::string
GUIServerImpl::getSequenceIdFromId(short id) {
CallMap::iterator iter = _callMap.find(id);
if (iter != _callMap.end()) {
return iter->second.sequenceId();
}
return "seq0";
}
short
GUIServerImpl::getIdFromCallId(const std::string& callId)
{
CallMap::iterator iter = _callMap.begin();
while (iter != _callMap.end()) {
if (iter->second.callId()==callId) {
return iter->first;
}
iter++;
}
throw std::runtime_error("No match for this CallId");
}
void
GUIServerImpl::hangup(const std::string& callId) {
try {
short id = getIdFromCallId(callId);
// There was a problem when hanging up...
if (!GuiFramework::hangupCall(id)) {
throw std::runtime_error("Error when hangup");
}
} catch(...) {
throw;
}
}
int
GUIServerImpl::incomingCall (short id)
{
return 0;
}
void
GUIServerImpl::peerAnsweredCall (short id)
{
CallMap::iterator iter = _callMap.find(id);
if ( iter != _callMap.end() ) {
_requestManager.sendResponse(ResponseMessage("200", iter->second.sequenceId(), "OK"));
} else {
std::ostringstream responseMessage;
responseMessage << "Peer Answered Call: " << id;
_requestManager.sendResponse(ResponseMessage("500", "seq0", responseMessage.str()));
}
}
int
GUIServerImpl::peerRingingCall (short id)
{
CallMap::iterator iter = _callMap.find(id);
if ( iter != _callMap.end() ) {
_requestManager.sendResponse(ResponseMessage("151", iter->second.sequenceId(), "Ringing"));
}
return 0;
}
int
GUIServerImpl::peerHungupCall (short id)
{
return 0;
}
void
GUIServerImpl::displayTextMessage (short id, const std::string& message)
{
std::ostringstream responseMessage;
std::string seq = getSequenceIdFromId(id);
responseMessage <<"s" << id << "text message: " + message;
_requestManager.sendResponse(ResponseMessage("700", seq, responseMessage.str()));
}
void
GUIServerImpl::displayErrorText (short id, const std::string& message)
{
std::ostringstream responseMessage;
std::string seq = getSequenceIdFromId(id);
responseMessage << "s" << id << " error text: " << message;
_requestManager.sendResponse(ResponseMessage("700", seq, responseMessage.str()));
}
void
GUIServerImpl::displayError (const std::string& error)
{
std::ostringstream responseMessage;
responseMessage << "error: " << error;
_requestManager.sendResponse(ResponseMessage("700", "seq0", responseMessage.str()));
}
void
GUIServerImpl::displayStatus (const std::string& status)
{
std::ostringstream responseMessage;
responseMessage << "status: " + status;
_requestManager.sendResponse(ResponseMessage("700", "seq0", responseMessage.str()));
}
void
GUIServerImpl::displayContext (short id)
{
std::ostringstream responseMessage;
responseMessage << "s" << id;
std::string seq = getSequenceIdFromId(id);
_requestManager.sendResponse(ResponseMessage("700", seq, responseMessage.str()));
}
std::string
GUIServerImpl::getRingtoneFile (void)
{
return std::string("");
}
void
GUIServerImpl::setup (void)
{
}
void
GUIServerImpl::startVoiceMessageNotification (void)
{
}
void
GUIServerImpl::stopVoiceMessageNotification (void)
{
}
/**
* 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 __GUI_SERVER_H__
#define __GUI_SERVER_H__
#include "../guiframework.h"
#include <string>
#include <map>
#include "subcall.h"
#include "requestmanager.h"
typedef std::map<short, SubCall> CallMap;
class GUIServerImpl : public GuiFramework {
public:
// GUIServerImpl constructor
GUIServerImpl();
// GUIServerImpl destructor
~GUIServerImpl();
// exec loop
int exec(void);
void insertSubCall(short id, SubCall& subCall);
void removeSubCall(short id);
std::string getSequenceIdFromId(short id);
short getIdFromCallId(const std::string& callId);
// Reimplementation of virtual functions
virtual int incomingCall (short id);
virtual void peerAnsweredCall (short id);
virtual int peerRingingCall (short id);
virtual int peerHungupCall (short id);
virtual void displayTextMessage (short id, const std::string& message);
virtual void displayErrorText (short id, const std::string& message);
virtual void displayError (const std::string& error);
virtual void displayStatus (const std::string& status);
virtual void displayContext (short id);
virtual std::string getRingtoneFile (void);
virtual void setup (void);
virtual void startVoiceMessageNotification (void);
virtual void stopVoiceMessageNotification (void);
bool outgoingCall (const std::string& seq,
const std::string& callid,
const std::string& to);
void hangup(const std::string& callId);
void quit() {_shouldQuit=true;}
private:
/**
* This callMap is necessary because
* ManagerImpl use callid-int
* and the client use a callid-string
* and also a sequence number
*/
CallMap _callMap;
// RequestManager execute received request
// and send response
RequestManager _requestManager;
bool _shouldQuit;
};
#endif // __GUI_SERVER_H__
/**
* 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 "requestmanager.h"
#include <iostream>
#include "tcpsessionio.h"
RequestManager::RequestManager() : _sessionIO(0)
{
_factory.registerAll();
}
RequestManager::~RequestManager()
{
flushWaitingRequest();
}
int
RequestManager::exec()
{
try {
ost::InetAddress addr("127.0.0.1");
//Creating a listening socket
ost::TCPSocket aServer(addr, 3999);
ResponseMessage outputResponse; // TCPStream output line
std::string input;
std::string output;
Request *request;
while (std::cin.good()) {
// 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()) {
if ( _sessionIO->receive(input)) {
request = _factory.create(input);
outputResponse = request->execute();
_sessionIO->send(outputResponse.toString());
handleExecutedRequest(request, outputResponse);
} // end pop
} // end streaming
} // end server side : ctrl + d
} catch(ost::Socket *e) {
std::cerr << e->getErrorString() << std::endl;
}
return 0;
}
/**
* Delete the request from the list of request
* or send it into the waitingRequest map
*/
void
RequestManager::handleExecutedRequest(Request * const request, const ResponseMessage& response)
{
if (response.isFinal()) {
delete request;
} else {
ost::MutexLock lock(_waitingRequestsMutex);
if (_waitingRequests.find(request->sequenceId()) == _waitingRequests.end()) {
// add the requests
_waitingRequests[response.sequenceId()] = request;
} else {
// we don't deal with requests with a sequenceId already send...
delete request;
}
}
}
/**
* Remove waiting requests that was not handle by the server
*/
void
RequestManager::flushWaitingRequest()
{
ost::MutexLock lock(_waitingRequestsMutex);
// Waiting Requests cleanup
std::map<std::string, Request*>::iterator iter = _waitingRequests.begin();
while (iter != _waitingRequests.end()) {
_waitingRequests.erase(iter);
delete (iter->second);
iter++;
}
}
/**
* This function is use by extern object
* to send response
*/
void
RequestManager::sendResponse(const ResponseMessage& response) {
if (_sessionIO) {
_sessionIO->send(response.toString());
} else {
std::cerr << "RequestManager::sendResponse: no initialize sessionIO" << response.toString() << std::endl;
}
// remove the request from the waiting requests list
if (response.isFinal()) {
ost::MutexLock lock(_waitingRequestsMutex);
std::map<std::string, Request*>::iterator iter = _waitingRequests.find(response.sequenceId());
if (iter != _waitingRequests.end()) {
_waitingRequests.erase(iter);
delete (iter->second);
}
}
}
/**
* 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 REQUESTMANAGER_H
#define REQUESTMANAGER_H
#include <cc++/thread.h>
#include "tcpsessionio.h"
#include "requestfactory.h"
#include "responsemessage.h"
/**
@author Yan Morin
*/
class RequestManager{
public:
RequestManager();
~RequestManager();
int exec(void);
void sendResponse(const ResponseMessage& response);
private:
void flushWaitingRequest();
void handleExecutedRequest(Request * const request, const ResponseMessage& response);
RequestFactory _factory;
TCPSessionIO* _sessionIO;
// waiting requests
ost::Mutex _waitingRequestsMutex;
std::map<std::string, Request*> _waitingRequests;
};
#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 "tcpsessionio.h"
void
TCPSessionIO::run() {
std::string output;
std::string input;
while(!testCancel() && good()) {
if (isPending(ost::TCPSocket::pendingInput, 10)) {
std::getline(*this, input);
_inputPool.push(input);
}
if (_outputPool.pop(output, 10LU)) {
*this << output << std::endl;
}
}
}
void
TCPSessionIO::send(const std::string& response)
{
_outputPool.push(response);
}
bool
TCPSessionIO::receive(std::string& request)
{
if ( _inputPool.pop(request, 10LU) ) {
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 TCPSESSIONIO_H
#define TCPSESSIONIO_H
#include <string>
#include <cc++/socket.h>
#include "ObjectPool.hpp"
/**
* Utilisation:
* 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
{
public:
TCPSessionIO(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