3 This file is part of the MSP Märklin suite
4 Copyright © 2009 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
8 #include <msp/net/inet.h>
9 #include "libmarklin/control.h"
10 #include "libmarklin/layout.h"
11 #include "libmarklin/locomotive.h"
12 #include "libmarklin/locotype.h"
13 #include "libmarklin/route.h"
21 Server::Server(TrafficManager &tm):
23 listen_sock(Net::INET),
26 const list<Train *> &trains = trfc_mgr.get_trains();
27 for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
30 listen_sock.listen(Net::InetAddr(0, 8315), 4);
31 listen_sock.signal_data_available.connect(sigc::mem_fun(this, &Server::incoming_connection));
34 void Server::use_event_dispatcher(IO::EventDispatcher &ed)
37 event_disp->add(listen_sock);
40 void Server::incoming_connection()
42 Net::StreamSocket *sock = listen_sock.accept();
44 event_disp->add(*sock);
45 connections.push_back(new Connection(*this, sock));
48 void Server::train_added(Train &train)
50 Locomotive &loco = train.get_locomotive();
51 train.signal_target_speed_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_speed_changed), sigc::ref(train)));
52 loco.signal_reverse_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_reverse_changed), sigc::ref(train)));
53 loco.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(train)));
54 train.signal_route_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_route_changed), sigc::ref(train)));
55 train.signal_status_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
58 pkt.address = loco.get_address();
59 pkt.loco_type = loco.get_type().get_article_number();
60 pkt.name = train.get_name();
64 void Server::train_speed_changed(const Train &train, unsigned speed)
67 pkt.address = train.get_locomotive().get_address();
69 pkt.reverse = train.get_locomotive().get_reverse();
73 void Server::train_reverse_changed(const Train &train, bool reverse)
76 pkt.address = train.get_locomotive().get_address();
77 pkt.speed = train.get_target_speed();
78 pkt.reverse = reverse;
82 void Server::train_function_changed(const Train &train, unsigned, bool)
84 TrainFunctionPacket pkt;
85 pkt.address = train.get_locomotive().get_address();
86 pkt.functions = train.get_locomotive().get_functions();
90 void Server::train_route_changed(const Train &train, const Route *route)
93 pkt.address = train.get_locomotive().get_address();
95 pkt.route = route->get_name();
99 void Server::train_status_changed(const Train &train, const string &status)
101 TrainStatusPacket pkt;
102 pkt.address = train.get_locomotive().get_address();
108 void Server::send(const P &pkt)
110 for(vector<Connection *>::const_iterator i=connections.begin(); i!=connections.end(); ++i)
112 (*i)->comm.send(pkt);
116 Server::Connection::Connection(Server &s, Net::StreamSocket *o):
119 comm(*socket, server.proto, *this)
121 socket->signal_end_of_file.connect(sigc::mem_fun(this, &Connection::end_of_file));
122 comm.signal_handshake_done.connect(sigc::mem_fun(this, &Connection::handshake_done));
123 comm.initiate_handshake();
126 Server::Connection::~Connection()
131 void Server::Connection::handshake_done()
133 const set<Route *> &routes = server.trfc_mgr.get_layout().get_routes();
134 for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
137 pkt.name = (*i)->get_name();
141 const list<Train *> &trains = server.trfc_mgr.get_trains();
142 for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
144 Locomotive &loco = (*i)->get_locomotive();
148 pkt.address = loco.get_address();
149 pkt.loco_type = loco.get_type().get_article_number();
150 pkt.name = (*i)->get_name();
154 TrainSpeedPacket pkt;
155 pkt.address = loco.get_address();
156 pkt.speed = (*i)->get_target_speed();
157 pkt.reverse = loco.get_reverse();
161 TrainFunctionPacket pkt;
162 pkt.address = loco.get_address();
163 pkt.functions = loco.get_functions();
167 TrainStatusPacket pkt;
168 pkt.address = loco.get_address();
169 pkt.status = (*i)->get_status();
172 if((*i)->get_route())
174 TrainRoutePacket pkt;
175 pkt.address = loco.get_address();
176 pkt.route = (*i)->get_route()->get_name();
182 void Server::Connection::end_of_file()
188 void Server::Connection::receive(const TrainSpeedPacket &pkt)
192 Locomotive &loco = server.trfc_mgr.get_control().get_locomotive(pkt.address);
193 Train &train = server.trfc_mgr.get_train_by_locomotive(loco);
194 if(pkt.reverse!=loco.get_reverse())
195 train.set_reverse(pkt.reverse);
197 train.set_speed(pkt.speed);
199 catch(const Exception &e)
205 void Server::Connection::receive(const TrainFunctionPacket &pkt)
209 Locomotive &loco = server.trfc_mgr.get_control().get_locomotive(pkt.address);
210 for(unsigned i=0; i<9; ++i)
211 if(((pkt.functions^loco.get_functions())>>i)&1)
212 loco.set_function(i, (pkt.functions>>i)&1);
214 catch(const Exception &e)
220 void Server::Connection::receive(const TrainRoutePacket &pkt)
224 Locomotive &loco = server.trfc_mgr.get_control().get_locomotive(pkt.address);
225 Train &train = server.trfc_mgr.get_train_by_locomotive(loco);
226 if(pkt.route.empty())
230 Route &route = server.trfc_mgr.get_layout().get_route(pkt.route);
231 train.set_route(&route);
234 catch(const Exception &e)
240 void Server::Connection::error(const string &msg)
247 } // namespace Marklin