summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp')
-rw-r--r--src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp
new file mode 100644
index 0000000..387075b
--- /dev/null
+++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp
@@ -0,0 +1,141 @@
+#ifdef _WIN32
+#include <winsock2.h>
+#include <windows.h>
+#endif
+
+#include "uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.h"
+#include "uscxml/Message.h"
+#include <iostream>
+#include <event2/dns.h>
+#include <event2/buffer.h>
+#include <event2/keyvalq_struct.h>
+
+#include <string.h>
+
+#include <io/uri.hpp>
+#include <glog/logging.h>
+
+#ifndef _WIN32
+#include <netdb.h>
+#include <arpa/inet.h>
+#endif
+
+#ifdef BUILD_AS_PLUGINS
+#include <Pluma/Connector.hpp>
+#endif
+
+namespace uscxml {
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_CONNECTOR
+bool connect(pluma::Host& host) {
+ host.add( new SCXMLIOProcessorProvider() );
+ return true;
+}
+#endif
+
+// see http://www.w3.org/TR/scxml/#SCXMLEventProcessor
+
+SCXMLIOProcessor::SCXMLIOProcessor() {
+}
+
+SCXMLIOProcessor::~SCXMLIOProcessor() {
+}
+
+
+boost::shared_ptr<IOProcessorImpl> SCXMLIOProcessor::create(InterpreterImpl* interpreter) {
+ boost::shared_ptr<SCXMLIOProcessor> io = boost::shared_ptr<SCXMLIOProcessor>(new SCXMLIOProcessor());
+ io->_interpreter = interpreter;
+
+ // register at http server
+ std::string path = interpreter->getName();
+ int i = 2;
+ while (!HTTPServer::registerServlet(path + "/scxml", io.get())) {
+ std::stringstream ss;
+ ss << interpreter->getName() << i++;
+ path = ss.str();
+ }
+ return io;
+}
+
+Data SCXMLIOProcessor::getDataModelVariables() {
+ Data data;
+ assert(_url.length() > 0);
+ data.compound["location"] = Data(_url, Data::VERBATIM);
+ return data;
+}
+
+
+void SCXMLIOProcessor::send(const SendRequest& req) {
+ // see http://www.w3.org/TR/scxml/#SendTargets
+
+ SendRequest reqCopy(req);
+ // test 253
+ reqCopy.origintype = "scxml";
+ reqCopy.origin = _url;
+
+ if (false) {
+ } else if (boost::iequals(reqCopy.target, "#_internal")) {
+ /**
+ * #_internal: If the target is the special term '#_internal', the Processor
+ * must add the event to the internal event queue of the sending session.
+ */
+ _interpreter->receiveInternal(reqCopy);
+
+ } else if(reqCopy.target.find_first_of("#_scxml_") == 0) {
+ /**
+ * #_scxml_sessionid: If the target is the special term '#_scxml_sessionid',
+ * where sessionid is the id of an SCXML session that is accessible to the
+ * Processor, the Processor must add the event to the external queue of that
+ * session. The set of SCXML sessions that are accessible to a given SCXML
+ * Processor is platform-dependent.
+ */
+ std::string sessionId = reqCopy.target.substr(8, reqCopy.target.length() - 8);
+ std::map<std::string, boost::weak_ptr<InterpreterImpl> > instances = Interpreter::getInstances();
+ if (instances.find(sessionId) != instances.end()) {
+ boost::shared_ptr<InterpreterImpl> other = instances[sessionId].lock();
+ other->receive(reqCopy);
+ } else {
+ LOG(ERROR) << "Can not send to scxml session " << sessionId << " - not known" << std::endl;
+ _interpreter->receiveInternal(Event("error.communication", Event::PLATFORM));
+ }
+
+
+ } else if (boost::iequals(reqCopy.target, "#_parent")) {
+ /**
+ * #_parent: If the target is the special term '#_parent', the Processor must
+ * add the event to the external event queue of the SCXML session that invoked
+ * the sending session, if there is one.
+ */
+ if (_interpreter->_parentQueue != NULL) {
+ _interpreter->_parentQueue->push(reqCopy);
+ } else {
+ LOG(ERROR) << "Can not send to parent, we were not invoked" << std::endl;
+ _interpreter->receiveInternal(Event("error.communication", Event::PLATFORM));
+ }
+ } else if (reqCopy.target.find_first_of("#_") == 0) {
+ /**
+ * #_invokeid: If the target is the special term '#_invokeid', where invokeid
+ * is the invokeid of an SCXML session that the sending session has created
+ * by <invoke>, the Processor must add the event to the external queue of that
+ * session.
+ */
+ std::string invokeId = reqCopy.target.substr(2, reqCopy.target.length() - 2);
+ if (_interpreter->_invokers.find(invokeId) != _interpreter->_invokers.end()) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_interpreter->_mutex);
+ try {
+ _interpreter->_invokers[invokeId].send(reqCopy);
+ } catch(...) {
+ LOG(ERROR) << "Exception caught while sending event to invoker " << invokeId;
+ }
+ } else {
+ LOG(ERROR) << "Can not send to invoked component '" << invokeId << "', no such invokeId" << std::endl;
+ _interpreter->receiveInternal(Event("error.communication", Event::PLATFORM));
+ }
+ } else {
+ }
+}
+
+
+
+} \ No newline at end of file