diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-08-14 08:11:54 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-08-14 08:11:54 (GMT) |
commit | 8684cefe080ab61d11d956d17ecfa417c2446dcc (patch) | |
tree | e8f53f52b8098d96d878d0a7f3b07b9b0ba094f3 /src/uscxml | |
parent | 66b0852b0618cc4bfff08d47aa0af56353226190 (diff) | |
download | uscxml-8684cefe080ab61d11d956d17ecfa417c2446dcc.zip uscxml-8684cefe080ab61d11d956d17ecfa417c2446dcc.tar.gz uscxml-8684cefe080ab61d11d956d17ecfa417c2446dcc.tar.bz2 |
JavaScriptCore in CMake module
Diffstat (limited to 'src/uscxml')
-rw-r--r-- | src/uscxml/Interpreter.cpp | 2 | ||||
-rw-r--r-- | src/uscxml/messages/Event.h | 16 | ||||
-rw-r--r-- | src/uscxml/messages/MMIMessages.cpp | 66 | ||||
-rw-r--r-- | src/uscxml/messages/MMIMessages.h | 12 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp | 160 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h | 18 | ||||
-rw-r--r-- | src/uscxml/server/HTTPServer.cpp | 2 |
7 files changed, 213 insertions, 63 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 7556961..ae620b8 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -1195,7 +1195,7 @@ void InterpreterImpl::send(const Arabica::DOM::Element<std::string>& element) { } Data namelistValue = _dataModel.getStringAsData(*nameIter); sendReq.namelist[*nameIter] = namelistValue; - sendReq.data.compound[*nameIter] = namelistValue; + sendReq.data.compound[*nameIter] = namelistValue; // this is questionable } } } catch (Event e) { diff --git a/src/uscxml/messages/Event.h b/src/uscxml/messages/Event.h index 1aa66a1..a63c55f 100644 --- a/src/uscxml/messages/Event.h +++ b/src/uscxml/messages/Event.h @@ -204,8 +204,8 @@ public: typedef std::multimap<std::string, Data> params_t; typedef std::map<std::string, Data> namelist_t; - - static bool getParam(params_t params, const std::string& name, Data& target) { + + static bool getParam(const params_t& params, const std::string& name, Data& target) { if (params.find(name) != params.end()) { target = params.find(name)->second; return true; @@ -213,9 +213,9 @@ public: return false; } - static bool getParam(params_t params, const std::string& name, std::list<Data>& target) { + static bool getParam(const params_t& params, const std::string& name, std::list<Data>& target) { if (params.find(name) != params.end()) { - std::pair<params_t::iterator, params_t::iterator> rangeIter = params.equal_range(name); + std::pair<params_t::const_iterator, params_t::const_iterator> rangeIter = params.equal_range(name); while(rangeIter.first != rangeIter.second) { target.push_back(rangeIter.first->second); rangeIter.first++; @@ -225,7 +225,7 @@ public: return false; } - template <typename T> static bool getParam(params_t params, const std::string& name, T& target) { + template <typename T> static bool getParam(const params_t& params, const std::string& name, T& target) { if (params.find(name) != params.end()) { target = boost::lexical_cast<T>(params.find(name)->second.atom); return true; @@ -233,7 +233,7 @@ public: return false; } - static bool getParam(params_t params, const std::string& name, bool& target) { + static bool getParam(const params_t& params, const std::string& name, bool& target) { if (params.find(name) != params.end()) { target = true; if (iequals(params.find(name)->second.atom, "false")) { @@ -250,9 +250,9 @@ public: return false; } - template <typename T> static bool getParam(params_t params, const std::string& name, std::list<T>& target) { + template <typename T> static bool getParam(const params_t& params, const std::string& name, std::list<T>& target) { if (params.find(name) != params.end()) { - std::pair<params_t::iterator, params_t::iterator> rangeIter = params.equal_range(name); + std::pair<params_t::const_iterator, params_t::const_iterator> rangeIter = params.equal_range(name); while(rangeIter.first != rangeIter.second) { target.push_back(boost::lexical_cast<T>(rangeIter.first->second.atom)); rangeIter.first++; diff --git a/src/uscxml/messages/MMIMessages.cpp b/src/uscxml/messages/MMIMessages.cpp index 1c5b98a..01705ed 100644 --- a/src/uscxml/messages/MMIMessages.cpp +++ b/src/uscxml/messages/MMIMessages.cpp @@ -119,22 +119,13 @@ Arabica::DOM::Document<std::string> MMIEvent::toXML(bool encapsulateInMMI) const if (data.size() > 0) { Element<std::string> dataElem = doc.createElementNS(nameSpace, "Data"); - - // try to parse content - std::stringstream* ss = new std::stringstream(); - (*ss) << data; - std::auto_ptr<std::istream> ssPtr(ss); - Arabica::SAX::InputSource<std::string> inputSource; - inputSource.setByteStream(ssPtr); - - NameSpacingParser parser; - if(parser.parse(inputSource)) { - Node<std::string> importedNode = doc.importNode(parser.getDocument().getDocumentElement(), true); - dataElem.appendChild(importedNode); - } else { - Text<std::string> textElem = doc.createTextNode(data); - dataElem.appendChild(textElem); - } + Text<std::string> textElem = doc.createTextNode(data); + dataElem.appendChild(textElem); + msgElem.appendChild(dataElem); + } else if (dataDOM) { + Element<std::string> dataElem = doc.createElementNS(nameSpace, "Data"); + Node<std::string> importNode = doc.importNode(dataDOM, true); + dataElem.appendChild(importNode); msgElem.appendChild(dataElem); } @@ -165,28 +156,16 @@ Arabica::DOM::Document<std::string> ContentRequest::toXML(bool encapsulateInMMI) contentURLElem.setAttributeNS(nameSpace, "fetchtimeout", contentURL.fetchTimeout); contentURLElem.setAttributeNS(nameSpace, "max-age", contentURL.maxAge); msgElem.appendChild(contentURLElem); - } - - if (content.size() > 0) { - Element<std::string> contentElem = doc.createElementNS(nameSpace, "content"); - - // try to parse content - std::stringstream* ss = new std::stringstream(); - (*ss) << content; - std::auto_ptr<std::istream> ssPtr(ss); - Arabica::SAX::InputSource<std::string> inputSource; - inputSource.setByteStream(ssPtr); - - Arabica::SAX2DOM::Parser<std::string> parser; - if(parser.parse(inputSource)) { - Node<std::string> importedNode = doc.importNode(parser.getDocument().getDocumentElement(), true); - contentElem.appendChild(importedNode); - } else { - Text<std::string> textElem = doc.createTextNode(content); - contentElem.appendChild(textElem); - } + } else if (contentDOM) { + Element<std::string> contentElem = doc.createElementNS(nameSpace, "Content"); + Node<std::string> importNode = doc.importNode(contentDOM, true); + contentElem.appendChild(importNode); + msgElem.appendChild(contentElem); + } else if (content.size() > 0) { + Element<std::string> contentElem = doc.createElementNS(nameSpace, "Content"); + Text<std::string> textElem = doc.createTextNode(content); + contentElem.appendChild(textElem); msgElem.appendChild(contentElem); - } return doc; } @@ -259,12 +238,15 @@ MMIEvent MMIEvent::fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl node = node.getNextSibling(); } - if (dataElem && boost::iequals(dataElem.getLocalName(), "data")) { - std::stringstream ss; + if (dataElem && boost::iequals(dataElem.getLocalName(), "data") && dataElem.getFirstChild()) { node = dataElem.getFirstChild(); - if (node) + if (node.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) { + msg.dataDOM = node; + } else { + std::stringstream ss; ss << node; - msg.data = ss.str(); + msg.data = ss.str(); + } } return msg; @@ -374,6 +356,8 @@ StatusResponse StatusResponse::fromXML(Arabica::DOM::Node<std::string> node, Int msg.status = FAILURE; } else if(boost::iequals(status, "SUCCESS")) { msg.status = SUCCESS; + } else { + msg.status = INVALID; } msg.type = STATUSRESPONSE; return msg; diff --git a/src/uscxml/messages/MMIMessages.h b/src/uscxml/messages/MMIMessages.h index e4456f8..c6a2fce 100644 --- a/src/uscxml/messages/MMIMessages.h +++ b/src/uscxml/messages/MMIMessages.h @@ -62,6 +62,7 @@ public: std::string source; std::string target; std::string data; + Arabica::DOM::Node<std::string> dataDOM; std::string requestId; std::string tagName; Type type; @@ -228,6 +229,7 @@ public: InterpreterImpl* interpreter = NULL); operator Event() const; std::string content; + Arabica::DOM::Node<std::string> contentDOM; ContentURL contentURL; protected: ContentRequest() {} @@ -296,15 +298,17 @@ protected: class StatusResponse : public ContextualizedRequest { public: enum Status { - ALIVE = 0, - DEAD = 1, - SUCCESS = 2, - FAILURE = 3 + INVALID = 0, + ALIVE = 1, + DEAD = 2, + SUCCESS = 3, + FAILURE = 4 }; StatusResponse() { tagName = "StatusResponse"; type = STATUSRESPONSE; + status = INVALID; } virtual Arabica::DOM::Document<std::string> toXML(bool encapsulateInMMI = false) const; static StatusResponse fromXML(Arabica::DOM::Node<std::string> node, diff --git a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp index 5a79094..7db9e66 100644 --- a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp @@ -32,7 +32,8 @@ name##XML.getDocumentElement().setPrefix("mmi");\ std::stringstream name##XMLSS;\ name##XMLSS << name##XML;\ - URL name##URL(target);\ + URL name##URL(name.target);\ + std::cout << "SEND: " << name##XMLSS.str() << std::endl; \ name##URL.setOutContent(name##XMLSS.str());\ name##URL.addOutHeader("Content-type", "application/xml");\ name##URL.download(false);\ @@ -49,6 +50,7 @@ bool pluginConnect(pluma::Host& host) { #endif VoiceXMLInvoker::VoiceXMLInvoker() { + _thread = NULL; } VoiceXMLInvoker::~VoiceXMLInvoker() { @@ -61,6 +63,79 @@ boost::shared_ptr<InvokerImpl> VoiceXMLInvoker::create(InterpreterImpl* interpre } bool VoiceXMLInvoker::httpRecvRequest(const HTTPServer::Request& request) { + tthread::lock_guard<tthread::mutex> lock(_mutex); + + if (!request.data.hasKey("content") || !request.data.at("content").node) { + HTTPServer::Reply reply(request); + reply.status = 500; + HTTPServer::reply(reply); + } + + const Arabica::DOM::Node<std::string>& node = request.data.at("content").node; + std::cout << "RCVD: " << node << std::endl; + + switch(MMIEvent::getType(node)) { + case MMIEvent::NEWCONTEXTRESPONSE: { + NewContextResponse resp = NewContextResponse::fromXML(node); + if (_context.size() == 0) { + _compState = MMI_IDLE; + _context = resp.context; + + StartRequest startReq; + startReq.context = _context; + startReq.source = _url; + startReq.target = _target; + startReq.requestId = uscxml::UUID::getUUID(); + + if (_invokeReq.src.size() > 0) { + startReq.contentURL.href = _invokeReq.src; + } else if(_invokeReq.content.size()) { + startReq.content = _invokeReq.content; + } else if(_invokeReq.dom) { + std::stringstream contentSS; + startReq.contentDOM = _invokeReq.dom; + } + ISSUE_REQUEST(startReq); + + } else { + // already got a context! + } + break; + } + case MMIEvent::STARTRESPONSE: { + StartResponse resp = StartResponse::fromXML(node); + _compState = MMI_RUNNING; + break; + } + + case MMIEvent::DONENOTIFICATION: { + DoneNotification resp = DoneNotification::fromXML(node); + _compState = MMI_IDLE; + break; + } + + case MMIEvent::EXTENSIONNOTIFICATION: { + ExtensionNotification resp = ExtensionNotification::fromXML(node); + Event ev; + ev.name = "mmi.extensionnotification"; + if (resp.dataDOM) { + ev.dom = resp.dataDOM; + } else if(resp.data.size() > 0) { + ev.data = Data::fromJSON(resp.data); // try to parse as JSON + if (ev.data.empty()) { + ev.content = resp.data; + } + } + returnEvent(ev); + } + + default: + break; + } + + + HTTPServer::Reply reply(request); + HTTPServer::reply(reply); return true; } @@ -74,17 +149,25 @@ Data VoiceXMLInvoker::getDataModelVariables() { } void VoiceXMLInvoker::send(const SendRequest& req) { + _workQueue.push(req); } void VoiceXMLInvoker::invoke(const InvokeRequest& req) { + tthread::lock_guard<tthread::mutex> lock(_mutex); + HTTPServer::getInstance()->registerServlet(req.invokeid, this); - std::string target; - Event::getParam(req.params, "target", target); + Event::getParam(req.params, "target", _target); + if (_target.size() == 0) { + LOG(ERROR) << "No target parameter given!"; + return; + } + + _invokeReq = req; NewContextRequest newCtxReq; newCtxReq.source = _url; - newCtxReq.target = target; + newCtxReq.target = _target; newCtxReq.requestId = uscxml::UUID::getUUID(); ISSUE_REQUEST(newCtxReq); @@ -93,6 +176,30 @@ void VoiceXMLInvoker::invoke(const InvokeRequest& req) { } +void VoiceXMLInvoker::uninvoke() { + + ClearContextRequest clrCtxReq; + clrCtxReq.source = _url; + clrCtxReq.target = _target; + clrCtxReq.requestId = uscxml::UUID::getUUID(); + ISSUE_REQUEST(clrCtxReq); + + if (_isRunning) + _isRunning = false; + + SendRequest req; + _workQueue.push(req); + + if (_thread) { + _thread->join(); + delete _thread; + } + + HTTPServer::getInstance()->unregisterServlet(this); + _context = ""; + +} + void VoiceXMLInvoker::run(void* instance) { VoiceXMLInvoker* INSTANCE = (VoiceXMLInvoker*)instance; while(true) { @@ -105,12 +212,47 @@ void VoiceXMLInvoker::run(void* instance) { } } -void VoiceXMLInvoker::process(SendRequest& ctx) { +void VoiceXMLInvoker::process(SendRequest& req) { + tthread::lock_guard<tthread::mutex> lock(_mutex); + while(_context.size() == 0 && _isRunning) + _cond.wait_for(_mutex, 200); -} + if (_context.size() == 0) { + // we never acquired a context + return; + } -void VoiceXMLInvoker::uninvoke() { - HTTPServer::getInstance()->unregisterServlet(this); -} + // dispatch over send request + + // if we did nothing else, send as ExtensionNotification + ExtensionNotification extNotif; + extNotif.context = _context; + extNotif.source = _url; + extNotif.target = _target; + extNotif.requestId = uscxml::UUID::getUUID(); + extNotif.name = req.name; + + if (!req.namelist.empty()) { + for (Event::namelist_t::iterator iter = req.namelist.begin(); iter != req.namelist.end(); iter++) { + req.data.compound[iter->first] = iter->second; + } + } else if (!req.params.empty()) { + for(Event::params_t::iterator it = req.params.begin(), end = req.params.end(); it != end; it = req.params.upper_bound(it->first)) { + Event::getParam(req.params, it->first, req.data.compound[it->first]); + } + } + + if (req.dom) { + extNotif.dataDOM = req.dom; + } else if (req.content.size() > 0) { + extNotif.data = req.content; + } else if (!req.data.empty()) { + extNotif.data = Data::toJSON(req.data); + } + + ISSUE_REQUEST(extNotif); + +} + }
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h index b70a073..6f2a248 100644 --- a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h +++ b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h @@ -34,6 +34,12 @@ namespace uscxml { class VoiceXMLInvoker : public InvokerImpl, public HTTPServlet { public: + enum ComponentState { + MMI_IDLE, + MMI_PAUSED, + MMI_RUNNING + }; + VoiceXMLInvoker(); virtual ~VoiceXMLInvoker(); virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter); @@ -46,6 +52,10 @@ public: return names; } + bool deleteOnUninvoke() { + return false; + } + bool httpRecvRequest(const HTTPServer::Request& request); void setURL(const std::string& url); @@ -59,8 +69,16 @@ public: protected: std::string _url; + std::string _context; + std::string _target; + + InvokeRequest _invokeReq; + + ComponentState _compState; tthread::thread* _thread; + tthread::condition_variable _cond; + tthread::mutex _mutex; concurrency::BlockingQueue<SendRequest> _workQueue; bool _isRunning; }; diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index a49bf4e..bbcbd37 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -115,7 +115,9 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss LOG(ERROR) << "WebSocket server cannot bind to tcp/" << _wsPort; } } + #if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES) + // have another look here https://github.com/ppelleti/https-example/blob/master/https-server.c _sslHandle = NULL; _https = NULL; if (!sslConf) { |