]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/centralstation.h
a34a3e361aeaffe8af82e36cf7e123346c5edad4
[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 std::string &);
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 void add_loco(unsigned, const std::string &, const VehicleType &);
141         virtual void remove_loco(unsigned);
142         virtual void set_loco_speed(unsigned, unsigned);
143         virtual void set_loco_reverse(unsigned, bool);
144         virtual void set_loco_function(unsigned, unsigned, bool);
145
146         virtual void add_turnout(unsigned, const TrackType &);
147         virtual void remove_turnout(unsigned);
148         virtual void set_turnout(unsigned, unsigned);
149         virtual unsigned get_turnout(unsigned) const;
150
151         virtual void add_signal(unsigned, const SignalType &);
152         virtual void remove_signal(unsigned);
153         virtual void set_signal(unsigned, unsigned);
154         virtual unsigned get_signal(unsigned) const;
155
156 private:
157         MagnetAccessory &add_accessory(unsigned, MagnetAccessory::Type, MagnetAccessory::Symbol);
158         void remove_accessory(unsigned);
159         void set_accessory_state(unsigned, MagnetAccessory::Type, unsigned);
160         unsigned get_accessory_state(unsigned, MagnetAccessory::Type) const;
161         void accessory_state_changed(const MagnetAccessory &) const;
162
163 public:
164         virtual void add_sensor(unsigned);
165         virtual void remove_sensor(unsigned);
166         virtual void set_sensor(unsigned, bool) { }
167         virtual bool get_sensor(unsigned) const;
168
169         virtual void tick();
170         virtual void flush();
171
172 private:
173         void command(const std::string &, bool = false);
174         Message receive();
175         void process_reply(const Message &);
176         void process_event(const Message &);
177         void process_object(unsigned, const Message::AttribMap &);
178         Protocol map_protocol(const std::string &) const;
179         template<typename T>
180         unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
181         void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
182         std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
183         Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
184         Message parse_message(std::string::iterator &, const std::string::iterator &) const;
185 };
186
187 } // namespace R2C2
188
189 #endif