From 78c07794bd9ed88d4a280140166a5909ad352f75 Mon Sep 17 00:00:00 2001 From: yanmorin <yanmorin> Date: Tue, 20 Sep 2005 19:57:12 +0000 Subject: [PATCH] Only one socket now for reading/writing. Call and hangup almost working. EventThread now listening event. Simple ArgTokenizer (without urlDecode yet) --- src/eventthread.cpp | 2 +- src/gui/official/test.cpp | 2 +- src/gui/server/Makefile.am | 2 +- src/gui/server/argtokenizer.h | 71 ++--------------- src/gui/server/guiserver.cpp | 120 ++++++++++++++++------------- src/gui/server/guiserver.h | 30 ++------ src/gui/server/request.cpp | 10 +++ src/gui/server/request.h | 8 +- src/gui/server/requestfactory.cpp | 3 + src/gui/server/responsemessage.cpp | 6 +- src/gui/server/responsemessage.h | 7 +- src/sipvoiplink.cpp | 7 ++ 12 files changed, 119 insertions(+), 149 deletions(-) diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 2caf0de457..fd25ed60e4 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -41,7 +41,7 @@ EventThread::~EventThread (void) void EventThread::run (void) { - while(testCancel()) { + while(!testCancel()) { _sipthread->getEvent(); } } diff --git a/src/gui/official/test.cpp b/src/gui/official/test.cpp index aa2ddf5e8b..93f145d183 100644 --- a/src/gui/official/test.cpp +++ b/src/gui/official/test.cpp @@ -6,7 +6,7 @@ int main(int, char**) { - std::istringstream s(std::string("100 seq12 Maréponse \"sldkfjdfj s;dlfk\"")); + std::istringstream s(std::string("100 seq12 Mar�onse \"sldk fjdfj\n\ns;d\tlfk\"")); std::string output; std::list< std::string > args; diff --git a/src/gui/server/Makefile.am b/src/gui/server/Makefile.am index 7e523e574a..2e0203e2c0 100644 --- a/src/gui/server/Makefile.am +++ b/src/gui/server/Makefile.am @@ -1,7 +1,7 @@ noinst_LTLIBRARIES = libsflphoneguiserver.la libsflphoneguiserver_la_SOURCES = $(BUILT_SOURCES) guiserver.cpp \ - responsemessage.cpp request.cpp requestfactory.cpp + responsemessage.cpp request.cpp requestfactory.cpp argtokenizer.cpp libsflphoneguiserver_la_CXXFLAGS = -DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" libsflphoneguiserver_la_LIBADD = diff --git a/src/gui/server/argtokenizer.h b/src/gui/server/argtokenizer.h index 7042d7699a..3c19b7ecde 100644 --- a/src/gui/server/argtokenizer.h +++ b/src/gui/server/argtokenizer.h @@ -22,13 +22,12 @@ #include <list> #include <string> -#include <iostream> typedef std::list<std::string> TokenList; /** Separate a string into token -a b "c d" = 3 tokens: [a], [b], [c d] +a b c%20d = 3 tokens: [a], [b], [c d] Example: #include <argtokenizer.h> @@ -45,68 +44,12 @@ public: ArgTokenizer() {} // ctor ~ArgTokenizer() {} // dtor - TokenList tokenize(const std::string& str) - { - TokenList stack; // token stack - std::string::size_type length = str.size(); - std::string::size_type i, pos; - std::string temp; - - bool inToken = false; // if we are inside a token or not - bool inQuote = false; // look if we are inside a "quoted-string" - char lastChar = '\0'; // lastChar for \" escaping inside quote - char c; - - pos = 0; // position inside quoted string, to escape backslashed-doublequote - for (i=0;i<length;i++) { - c = str[i]; - // for the new token - if (inToken == false) { - if (c == ' ') { continue; } // escape space outside a token - else if (c == '"') { - inToken = true; - inQuote = true; - lastChar = '\0'; - pos = 0; - continue; - } else { - inToken = true; - } - } - if (inToken) { - // we are inside a token - if (inQuote) { // we are looking for a " token - if ( c == '"' ) { - if (lastChar == '\\') { - temp[pos-1] = '"'; - } else { // end of the string - if (temp.size()) { stack.push_back(temp); temp=""; } - temp = ""; - inToken = false; - inQuote = false; - } - } else { // normal character to append - temp += c; - pos++; - } - lastChar = c; - } else { // not in quote, stop to first space - if ( c == ' ' ) { - if (temp.size()) { stack.push_back(temp); temp=""; } - inToken = false; - } else { - temp += c; - } - } - } - } - if (temp.size()) { stack.push_back(temp); } // add last keyword - - return stack; - } - - // look at http://yansanmo.no-ip.org/test/cpp/argtokenizer.h - // for test + /** + * Tokenize a string into a list of string + * Separators are: space, newline and tab ( ,\n,\t) + * @author: Jean-Philippe Barrette-LaPierre + */ + TokenList tokenize(const std::string& str); }; #endif // __ARG_TOKENIZER__ diff --git a/src/gui/server/guiserver.cpp b/src/gui/server/guiserver.cpp index b6f63861e0..dab7006600 100644 --- a/src/gui/server/guiserver.cpp +++ b/src/gui/server/guiserver.cpp @@ -20,31 +20,27 @@ #include "guiserver.h" #include <string> #include <iostream> +#include <sstream> +#include <stdexcept> #include "responsemessage.h" #include "request.h" void -TCPSessionReader::run() -{ +TCPSessionIO::run() { while(!testCancel() && good()) { - std::string output; - std::getline(*this, output); - _gui->pushRequestMessage(output); - } -} - -void -TCPSessionWriter::run() -{ - while (!testCancel() && good()) { - *this << _gui->popResponseMessage() << std::endl; + if (isPending(ost::TCPSocket::pendingInput)) { + std::string output; + std::getline(*this, output); + _gui->pushRequestMessage(output); + } } } // default constructor GUIServer::GUIServer() { - _factory.registerAll();} + _factory.registerAll(); +} // destructor GUIServer::~GUIServer() @@ -70,16 +66,13 @@ GUIServer::exec() { std::cout << "waiting for a new connection..." << std::endl; //I'm accepting an incomming connection - sessionIn = new TCPSessionReader(aServer, this); - sessionOut = new TCPSessionWriter(aServer, this); - - sessionIn->start(); - sessionOut->start(); + _sessionIO = new TCPSessionIO(aServer, this); + _sessionIO->start(); // wait for the first message std::cout << "accepting connection..." << std::endl; - while(sessionIn->good() && sessionOut->good()) { + while(_sessionIO->good()) { request = popRequest(); output = request->execute(*this); pushResponseMessage(output); @@ -108,7 +101,7 @@ GUIServer::popRequest() Request *request = 0; while(!request) { _mutex.enterMutex(); - if ( _requests.size() ) { + if ( _requests.begin() != _requests.end() ) { request = _requests.front(); _requests.pop_front(); } @@ -122,7 +115,7 @@ GUIServer::pushResponseMessage(const ResponseMessage &response) { std::cout << "pushResponseMessage" << std::endl; _mutex.enterMutex(); - _responses.push_back(response.toString()); + *_sessionIO << response.toString() << std::endl; _mutex.leaveMutex(); // remove the request from the list @@ -131,23 +124,6 @@ GUIServer::pushResponseMessage(const ResponseMessage &response) } } -std::string -GUIServer::popResponseMessage() -{ - bool canPop = false; - std::string message; - while(!canPop) { - _mutex.enterMutex(); - if ( _responses.size() ) { - message = _responses.front(); - _responses.pop_front(); - canPop = true; - } - _mutex.leaveMutex(); - } - return message; -} - /** * Remove a request with its sequence id */ @@ -177,6 +153,41 @@ GUIServer::removeSubCall(short id) { _callMap.erase(id); } +/** + * Retreive the subcall or send 0 + */ +std::string +GUIServer::getSequenceIdFromId(short id) { + CallMap::iterator iter = _callMap.find(id); + if (iter != _callMap.end()) { + return iter->second.sequenceId(); + } + return "seq0"; +} + +short +GUIServer::getIdFromCallId(const std::string& callId) +{ + CallMap::iterator iter = _callMap.begin(); + while (iter != _callMap.end()) { + if (iter->second.callId()==callId) { + return iter->first; + } + } + throw std::runtime_error("No match for this CallId"); +} + +void +GUIServer::hangup(const std::string& callId) { + try { + short id = getIdFromCallId(callId); + if (!GuiFramework::hangupCall(id)) { + throw std::runtime_error("Error when hangup"); + } + } catch(...) { + throw; + } +} int GUIServer::incomingCall (short id) @@ -212,39 +223,44 @@ GUIServer::peerHungupCall (short id) void GUIServer::displayTextMessage (short id, const std::string& message) { - std::string responseMessage = "s"; - responseMessage += id + " text message: " + message; - pushResponseMessage(ResponseMessage("700", "seq0", responseMessage)); + std::ostringstream responseMessage; + std::string seq = getSequenceIdFromId(id); + responseMessage <<"s" << id << "text message: " + message; + pushResponseMessage(ResponseMessage("700", seq, responseMessage.str())); } void GUIServer::displayErrorText (short id, const std::string& message) { - std::string responseMessage = "s"; - responseMessage += id + " error text: " + message; - pushResponseMessage(ResponseMessage("700", "seq0", responseMessage)); + std::ostringstream responseMessage; + std::string seq = getSequenceIdFromId(id); + responseMessage << "s" << id << " error text: " << message; + pushResponseMessage(ResponseMessage("700", seq, responseMessage.str())); } void GUIServer::displayError (const std::string& error) { - std::string responseMessage = "error: " + error; - pushResponseMessage(ResponseMessage("700", "seq0", responseMessage)); + std::ostringstream responseMessage; + responseMessage << "error: " << error; + pushResponseMessage(ResponseMessage("700", "seq0", responseMessage.str())); } void GUIServer::displayStatus (const std::string& status) { - std::string responseMessage = "status: " + status; - pushResponseMessage(ResponseMessage("700", "seq0", responseMessage)); + std::ostringstream responseMessage; + responseMessage << "status: " + status; + pushResponseMessage(ResponseMessage("700", "seq0", responseMessage.str())); } void GUIServer::displayContext (short id) { - std::string responseMessage = "s"; - responseMessage += id; - pushResponseMessage(ResponseMessage("700", "seq0", responseMessage)); + std::ostringstream responseMessage; + responseMessage << "s" << id; + std::string seq = getSequenceIdFromId(id); + pushResponseMessage(ResponseMessage("700", seq, responseMessage.str())); } std::string diff --git a/src/gui/server/guiserver.h b/src/gui/server/guiserver.h index 3f1981bce8..40b0a52abb 100644 --- a/src/gui/server/guiserver.h +++ b/src/gui/server/guiserver.h @@ -31,10 +31,10 @@ #include "requestfactory.h" class GUIServer; -class TCPSessionReader : public ost::TCPSession +class TCPSessionIO : public ost::TCPSession { public: - TCPSessionReader(ost::TCPSocket &server, GUIServer *gui) : + TCPSessionIO(ost::TCPSocket &server, GUIServer *gui) : ost::TCPSession(server), _gui(gui) {} @@ -44,20 +44,6 @@ private: GUIServer *_gui; }; -class TCPSessionWriter : public ost::TCPSession -{ -public: - TCPSessionWriter(ost::TCPSocket &server, GUIServer *gui) : - ost::TCPSession(server), - _gui(gui) {} - - void run(); - -private: - GUIServer *_gui; -}; - - typedef std::map<short, SubCall> CallMap; class ResponseMessage; class GUIServer : public GuiFramework { @@ -72,13 +58,13 @@ public: void pushRequestMessage(const std::string& request); Request *popRequest(void); void pushResponseMessage(const ResponseMessage& response); - std::string popResponseMessage(void); void removeRequest(const std::string& sequenceId); 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); @@ -97,10 +83,11 @@ public: virtual void stopVoiceMessageNotification (void); int outgoingCall (const std::string& to) {return GuiFramework::outgoingCall(to);} + void hangup(const std::string& callId); private: - ost::TCPSession* sessionIn; - ost::TCPSession* sessionOut; + ost::TCPSession* _sessionIO; + /** * This callMap is necessary because * ManagerImpl use callid-int @@ -109,7 +96,6 @@ private: */ CallMap _callMap; std::list<Request*> _requests; - std::list<std::string> _responses; RequestFactory _factory; ost::Mutex _mutex; }; diff --git a/src/gui/server/request.cpp b/src/gui/server/request.cpp index 5bd675236d..91ccf32b21 100644 --- a/src/gui/server/request.cpp +++ b/src/gui/server/request.cpp @@ -34,4 +34,14 @@ RequestCall::execute(GUIServer& gui) } } +ResponseMessage +RequestHangup::execute(GUIServer& gui) +{ + try { + gui.hangup(_callId); + return message("200", "OK"); + } catch (...) { + return message("500", "Hangup Error"); + } +} diff --git a/src/gui/server/request.h b/src/gui/server/request.h index 3701debcb9..c07a65cbdf 100644 --- a/src/gui/server/request.h +++ b/src/gui/server/request.h @@ -44,7 +44,7 @@ public: virtual ~Request() {} virtual ResponseMessage execute(GUIServer& gui) = 0; ResponseMessage message(const std::string &code, const std::string &message) { - ResponseMessage response(_sequenceId, code, message); + ResponseMessage response(code, _sequenceId, message); return response; } std::string sequenceId () const { return _sequenceId; } @@ -131,7 +131,11 @@ class RequestTransfer : public RequestGlobalCall { public: RequestTransfer(const std::string &sequenceId, const TokenList& argList) : RequestGlobalCall(sequenceId,argList) {} }; - +class RequestHangup : public RequestGlobalCall { +public: + RequestHangup(const std::string &sequenceId, const TokenList& argList) : RequestGlobalCall(sequenceId,argList) {} + ResponseMessage execute(GUIServer& gui); +}; class RequestGlobal : public Request { diff --git a/src/gui/server/requestfactory.cpp b/src/gui/server/requestfactory.cpp index ae76e5c1fb..677049aa6d 100644 --- a/src/gui/server/requestfactory.cpp +++ b/src/gui/server/requestfactory.cpp @@ -28,11 +28,13 @@ RequestFactory::create(const std::string& requestLine) TokenList tList = _tokenizer.tokenize(requestLine); TokenList::iterator iter = tList.begin(); + // there is atleast one token (the command) if (iter != tList.end()) { std::string requestName = *iter; tList.pop_front(); iter = tList.begin(); + // there is atleast a second token (the sequenceId) if (iter != tList.end() && iter->find("seq") == 0 ) { std::string sequenceId = *iter; @@ -89,6 +91,7 @@ RequestFactory::registerAll() { registerRequest<RequestRefuse> ("refuse"); registerRequest<RequestHold> ("hold"); registerRequest<RequestUnhold> ("unhold"); + registerRequest<RequestHangup> ("hangup"); registerRequest<RequestTransfer> ("transfer"); registerRequest<RequestMute> ("mute"); registerRequest<RequestUnmute> ("unmute"); diff --git a/src/gui/server/responsemessage.cpp b/src/gui/server/responsemessage.cpp index ce030455d2..46dc17d4c8 100644 --- a/src/gui/server/responsemessage.cpp +++ b/src/gui/server/responsemessage.cpp @@ -24,9 +24,9 @@ */ const std::string ResponseMessage::FINALCODE = "2456"; -ResponseMessage::ResponseMessage(const std::string& seq, - const std::string& code, - const std::string& message) : _seq(seq), _code(code), _message(message) +ResponseMessage::ResponseMessage(const std::string& code, + const std::string& seq, + const std::string& message) : _code(code), _seq(seq), _message(message) { } diff --git a/src/gui/server/responsemessage.h b/src/gui/server/responsemessage.h index eae2c0c20e..2a2522ea9a 100644 --- a/src/gui/server/responsemessage.h +++ b/src/gui/server/responsemessage.h @@ -29,8 +29,9 @@ class ResponseMessage public: // default constructor with empty seq/code/message ResponseMessage() {} - ResponseMessage(const std::string& seq, const std::string& code,const std::string& message - ); + // build a constructor with a TokenList + // so that they will be encoded.. + ResponseMessage(const std::string& code,const std::string& seq, const std::string& message); ~ResponseMessage(); std::string sequenceId() const { return _seq; } @@ -39,8 +40,8 @@ public: bool isFinal() const; private: // 3 numbers long sequenceId - std::string _seq; std::string _code; + std::string _seq; std::string _message; static const std::string FINALCODE; diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index cf317dd3ab..fb3cb8e0a1 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -547,6 +547,7 @@ SipVoIPLink::getEvent (void) return -1; } + Manager::instance().displayErrorText(event->type, "getEvent"); switch (event->type) { // IP-Phone user receives a new call case EXOSIP_CALL_INVITE: // @@ -820,7 +821,13 @@ SipVoIPLink::getEvent (void) } break; + case EXOSIP_CALL_RELEASED: + //TODO: find the id... + Manager::instance().displayErrorText(0, "getEvent:CallReleased"); + + break; default: + Manager::instance().displayErrorText(event->type, "getEvent:default"); return -1; break; } -- GitLab