]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/centralstation.h
f23fa66806cb809e7be4de1edc934811a227fabe
[r2c2.git] / source / libr2c2 / centralstation.h
1 #ifndef LIBR2C2_CENTRALSTATION_H_
2 #define LIBR2C2_CENTRALSTATION_H_
3
4 #include <msp/net/streamsocket.h>
5 #include <msp/time/timestamp.h>
6 #include "driver.h"
7
8 namespace R2C2 {
9
10 class CentralStation: public Driver
11 {
12 private:
13         struct Tag
14         {
15                 std::string type;
16                 unsigned code;
17                 std::string value;
18
19                 Tag();
20
21                 operator bool() const;
22         };
23
24         struct Message
25         {
26                 typedef std::multimap<std::string, std::string> AttribMap;
27                 typedef std::map<unsigned, AttribMap> ObjectMap;
28         
29                 Tag header;
30                 ObjectMap content;
31                 Tag footer;
32
33                 operator bool() const;
34         };
35
36         enum Error
37         {
38                 OK,
39                 NERROR_UNKNOWNCOMMAND = 10,
40                 NERROR_UNKNOWNARG = 11,
41                 NERROR_UNKNOWNPARAM = 12,
42                 NERROR_UNKNOWNID = 15,
43                 NERROR_SIZE = 20,
44                 NERROR_NOTALLOWED = 22,
45                 NERROR_NOCONTROL = 25,
46                 NERROR_NOCREATE = 28,
47                 NERROR_NOARG = 29
48         };
49
50         enum Protocol
51         {
52                 MM,
53                 MM_27,
54                 MFX
55         };
56
57         struct Locomotive
58         {
59                 std::string name;
60                 Protocol protocol;
61                 unsigned address;
62                 unsigned speed;
63                 bool reverse;
64                 unsigned func_mask;
65                 unsigned funcs;
66                 bool control;
67
68                 Locomotive();
69         };
70
71         struct MagnetAccessory
72         {
73                 enum Type
74                 {
75                         TURNOUT,
76                         SIGNAL
77                 };
78
79                 enum Symbol
80                 {
81                         TURNOUT_LEFT = 0,
82                         TURNOUT_RIGHT = 1,
83                         TURNOUT_THREEWAY = 2,
84                         TURNOUT_DOUBLESLIP = 3,
85                         SEMAPHORE_HOME = 5,
86                         TURNOUT_CURVED_LEFT = 21,
87                         TURNOUT_CURVED_RIGHT = 22
88                 };
89
90                 unsigned address;
91                 Type type;
92                 Symbol symbol;
93                 unsigned state;
94                 unsigned bits;
95                 bool synced;
96
97                 MagnetAccessory();
98         };
99
100         struct Sensor
101         {
102                 bool state;
103
104                 Sensor();
105         };
106
107         typedef std::map<unsigned, unsigned> AddressMap;
108         typedef std::map<unsigned, Locomotive> LocoMap;
109         typedef std::map<unsigned, MagnetAccessory> AccessoryMap;
110         typedef std::map<unsigned, Sensor> SensorMap;
111
112         Msp::Net::StreamSocket socket;
113         std::list<std::string> cmd_queue;
114         unsigned pending_commands;
115         bool power;
116         bool halted;
117         std::string in_buffer;
118         LocoMap locos;
119         AddressMap loco_addr;
120         bool locos_synced;
121         AccessoryMap accessories;
122         AddressMap accessory_addr;
123         bool accessories_synced;
124         SensorMap sensors;
125         std::vector<unsigned> s88;
126         bool sensors_synced;
127
128 public:
129         CentralStation(const Options &);
130         ~CentralStation();
131
132         virtual void set_power(bool);
133         virtual bool get_power() const { return power; }
134         virtual void halt(bool);
135         virtual bool is_halted() const { return halted; }
136
137         virtual const char *enumerate_protocols(unsigned) const;
138         virtual unsigned get_protocol_speed_steps(const std::string &) const;
139
140         virtual DetectedLocomotive *enumerate_detected_locos(unsigned) const { return 0; }
141         virtual unsigned add_loco(unsigned, const std::string &, const VehicleType &);
142         virtual void remove_loco(unsigned);
143         virtual void set_loco_speed(unsigned, unsigned);
144         virtual void set_loco_reverse(unsigned, bool);
145         virtual void set_loco_function(unsigned, unsigned, bool);
146
147         virtual unsigned add_turnout(unsigned, const TrackType &);
148         virtual void remove_turnout(unsigned);
149         virtual void set_turnout(unsigned, unsigned);
150         virtual unsigned get_turnout(unsigned) const;
151
152         virtual unsigned add_signal(unsigned, const SignalType &);
153         virtual void remove_signal(unsigned);
154         virtual void set_signal(unsigned, unsigned);
155         virtual unsigned get_signal(unsigned) const;
156
157 private:
158         MagnetAccessory &add_accessory(unsigned, MagnetAccessory::Type, MagnetAccessory::Symbol);
159         void remove_accessory(unsigned);
160         void set_accessory_state(unsigned, MagnetAccessory::Type, unsigned);
161         unsigned get_accessory_state(unsigned, MagnetAccessory::Type) const;
162         void accessory_state_changed(const MagnetAccessory &) const;
163
164 public:
165         virtual unsigned add_sensor(unsigned);
166         virtual void remove_sensor(unsigned);
167         virtual void set_sensor(unsigned, bool) { }
168         virtual bool get_sensor(unsigned) const;
169
170         virtual void tick();
171         virtual void flush();
172
173 private:
174         void command(const std::string &, bool = false);
175         Message receive();
176         void process_reply(const Message &);
177         void process_event(const Message &);
178         void process_object(unsigned, const Message::AttribMap &);
179         Protocol map_protocol(const std::string &) const;
180         template<typename T>
181         unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
182         void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
183         std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
184         Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
185         Message parse_message(std::string::iterator &, const std::string::iterator &) const;
186 };
187
188 } // namespace R2C2
189
190 #endif