dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / scd_in_connector.cpp
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_in_connector.cpp b/dol/src/dol/visitor/hdsd/scd/scd_in_connector.cpp
new file mode 100644 (file)
index 0000000..e289d25
--- /dev/null
@@ -0,0 +1,130 @@
+#include "scd_in_connector.h"
+
+#include "scd_logging.h"
+#include "scd_cont_man_master.h"
+
+
+scd_in_connector::scd_in_connector(scd_simulator &sim, scd_socket* sock):
+    _sim(sim), _socket(sock), _is_connecting(true)
+{
+    // register this event handler
+    _sim.get_poller().register_handler(*this, SOCK_EV_READ | SOCK_EV_CLOSE);
+
+    // set the socket for the reader
+    _reader.set_socket(*sock);
+}
+
+
+scd_in_connector::~scd_in_connector()
+{
+    if (_is_connecting)
+    {
+        _cleanup();
+    }
+}
+
+
+bool scd_in_connector::is_connecting() { return _is_connecting; }
+
+
+void scd_in_connector::handle_sock_ev(sock_ev events)
+{
+    if (events & SOCK_EV_CLOSE)
+    {
+        scd_debug("in_connector: received close event");
+        _cleanup();
+    }
+    else if (events & SOCK_EV_READ)
+    {
+        _reader.read();
+
+        if (!_socket->is_valid())
+        {
+            // connection closed
+            _cleanup();
+            scd_debug("in_connector: connection closed");
+            return;
+        }
+
+        if (!_reader.is_reading() && !_reader.has_command())
+        {
+            // received an illegal command
+            scd_debug("in_connector: received illegal command");
+            _cleanup();
+            return;
+        }
+
+        if (_reader.has_command())
+        {
+            scd_command* cmd = _reader.get_command();
+
+            if (cmd->get_type() == SCD_CM_REGISTER &&
+                    cmd->get_subtype() == SCD_CM_NETSIM)
+            {
+                // register host
+                scd_debug("in_connector: received cmd \"register host\"");
+
+                try
+                {
+                    // check if we are the master
+                    scd_cont_man_master& master =
+                        dynamic_cast<scd_cont_man_master&>(_sim.get_cont_man());
+
+                    _sim.get_poller().remove_handler(*this);
+
+                    master.connect_slave(*cmd, _socket);
+
+                    delete cmd;
+                    _is_connecting = false;
+                    return;
+                }
+                catch ( std::bad_cast e)
+                {
+                    scd_warn("slave tried to register");
+                    delete cmd;
+                    _cleanup();
+                    return;
+                }
+            } // end register host
+            else if (cmd->get_type() == SCD_CM_REGISTER &&
+                    cmd->get_subtype() == SCD_CM_CHANNEL)
+            {
+                // register channel
+                scd_debug("in_connector: received cmd \"register channel\"");
+
+                _sim.get_poller().remove_handler(*this);
+
+                _sim.get_chan_man().connect_channel(*cmd, _socket);
+
+                delete cmd;
+                _is_connecting = false;
+                return;
+            } // end register channel
+            else
+            {
+                // received wrong command
+                scd_debug("in_connector: received unknown command");
+                delete cmd;
+                _cleanup();
+                return;
+            }
+        } // end receive command
+    } // end read event
+
+} // handle_sock_ev()
+
+
+const scd_socket& scd_in_connector::get_sock()
+{
+    return *_socket;
+}
+
+
+void scd_in_connector::_cleanup()
+{
+    if (_is_connecting)
+        _sim.get_poller().remove_handler(*this);
+    _socket->close();
+    delete _socket;
+    _is_connecting = false;
+}