1 #include "scd_out_connector.h"
5 #include "scd_logging.h"
6 #include "scd_exception.h"
7 #include "scd_command.h"
10 scd_out_connector::scd_out_connector(scd_simulator& sim, uint16_t type,
11 const std::string& name):
12 _sim(sim), _name(name),
13 _is_connecting(true), _is_connected(false), _has_connection(false)
16 _socket = new scd_socket;
19 // prepare register command (do not send yet)
20 scd_command* cmd = new scd_command(SCD_CM_REGISTER, type, name);
21 _writer = new scd_command_writer();
22 _writer->set_socket(*_socket);
23 _writer->queue_command(cmd);
27 scd_out_connector::~scd_out_connector()
34 void scd_out_connector::connect_to(const std::string& host, uint16_t port)
39 // register the handler to check if a connection attempt succeeded
40 _sim.get_poller().register_handler(*this, SOCK_EV_WRITE);
42 // start connection attempt
48 bool scd_out_connector::is_connecting() { return _is_connecting; }
51 bool scd_out_connector::has_connection() { return _has_connection; }
54 scd_socket* scd_out_connector::get_connection()
58 _has_connection = false;
66 void scd_out_connector::process()
68 if (_is_connecting && !_is_connected)
71 gettimeofday(&now, NULL);
73 // check if an attempt had timed out (i.e. because of "drop" FW policy)
74 if ( _socket->is_connecting() &&
75 (now.tv_sec - _last_con.tv_sec >= SCD_CON_TIMEOUT) )
77 // close and reopen the socket
78 scd_debug("connecting to " + _host + " timed out");
79 _sim.get_poller().remove_handler(*this);
82 _sim.get_poller().register_handler(*this, 0);
85 // check if it is time to try again
86 if ( !_socket->is_connecting() &&
87 (now.tv_sec - _last_con.tv_sec >= SCD_CON_RETRY) )
89 scd_debug("reconnecting to " + _host);
91 _sim.get_poller().set_ev(*this, SOCK_EV_WRITE);
93 } // still trying to tcp-connect
98 void scd_out_connector::close()
102 _sim.get_poller().remove_handler(*this);
105 if (_is_connecting || _has_connection)
110 _is_connecting = false;
111 _has_connection = false;
114 _is_connected = false;
119 const std::string& scd_out_connector::get_name() const { return _name; }
122 void scd_out_connector::handle_sock_ev(sock_ev events)
124 if (events & SOCK_EV_CLOSE)
126 // the close event is only polled if _is_connected is true
127 scd_error("outgoing connection closed");
131 else if (events & SOCK_EV_WRITE)
135 if (_socket->connected_event())
137 // connection established
138 scd_debug("ougoing connection established to " + _host);
139 _is_connected = true;
140 _sim.get_poller().set_ev(*this, SOCK_EV_WRITE | SOCK_EV_CLOSE);
144 // connection attempt failed
145 _sim.get_poller().set_ev(*this, 0);
150 assert( _is_connected || !_socket->is_connecting());
153 if (!_writer->is_writing())
155 // done sending the command
156 _is_connecting = false;
157 _has_connection = true;
158 _sim.get_poller().remove_handler(*this);
161 if (!_socket->is_valid())
167 } // handle_sock_ev()
170 const scd_socket& scd_out_connector::get_sock() { return *_socket; }
173 void scd_out_connector::_conn_attempt()
175 if (_socket->connect(_host, _port))
177 gettimeofday(&_last_con, NULL);
181 scd_error("unable to connect to " + _host);