]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/centralstation.h
ad3d771f312094e3098b9d5aa2979a8b8b1a6498
[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                 };
77
78                 enum Symbol
79                 {
80                         TURNOUT_LEFT = 0,
81                         TURNOUT_RIGHT = 1,
82                         TURNOUT_THREEWAY = 2,
83                         TURNOUT_DOUBLESLIP = 3,
84                         TURNOUT_CURVED_LEFT = 21,
85                         TURNOUT_CURVED_RIGHT = 22
86                 };
87
88                 unsigned address;
89                 Type type;
90                 Symbol symbol;
91                 unsigned state;
92                 unsigned bits;
93                 bool synced;
94
95                 MagnetAccessory();
96         };
97
98         struct Sensor
99         {
100                 bool state;
101
102                 Sensor();
103         };
104
105         typedef std::map<unsigned, unsigned> AddressMap;
106         typedef std::map<unsigned, Locomotive> LocoMap;
107         typedef std::map<unsigned, MagnetAccessory> AccessoryMap;
108         typedef std::map<unsigned, Sensor> SensorMap;
109
110         Msp::Net::StreamSocket socket;
111         std::list<std::string> cmd_queue;
112         unsigned pending_commands;
113         bool power;
114         bool halted;
115         std::string in_buffer;
116         LocoMap locos;
117         AddressMap loco_addr;
118         bool locos_synced;
119         AccessoryMap accessories;
120         AddressMap accessory_addr;
121         bool accessories_synced;
122         SensorMap sensors;
123         std::vector<unsigned> s88;
124         bool sensors_synced;
125
126 public:
127         CentralStation(const std::string &);
128         ~CentralStation();
129
130         virtual void set_power(bool);
131         virtual bool get_power() const { return power; }
132         virtual void halt(bool);
133         virtual bool is_halted() const { return halted; }
134
135         virtual const char *enumerate_protocols(unsigned) const;
136         virtual unsigned get_protocol_speed_steps(const std::string &) const;
137
138         virtual void add_loco(unsigned, const std::string &, const VehicleType &);
139         virtual void set_loco_speed(unsigned, unsigned);
140         virtual void set_loco_reverse(unsigned, bool);
141         virtual void set_loco_function(unsigned, unsigned, bool);
142
143         virtual void add_turnout(unsigned, const TrackType &);
144         virtual void set_turnout(unsigned, unsigned);
145         virtual unsigned get_turnout(unsigned) const;
146
147 private:
148         MagnetAccessory &add_accessory(unsigned, MagnetAccessory::Type, MagnetAccessory::Symbol);
149         void set_accessory_state(unsigned, MagnetAccessory::Type, unsigned);
150         unsigned get_accessory_state(unsigned, MagnetAccessory::Type) const;
151         void accessory_state_changed(const MagnetAccessory &) const;
152
153 public:
154         virtual void add_sensor(unsigned);
155         virtual void set_sensor(unsigned, bool) { }
156         virtual bool get_sensor(unsigned) const;
157
158         virtual void tick();
159         virtual void flush();
160
161 private:
162         void command(const std::string &, bool = false);
163         Message receive();
164         void process_reply(const Message &);
165         void process_event(const Message &);
166         void process_object(unsigned, const Message::AttribMap &);
167         Protocol map_protocol(const std::string &) const;
168         template<typename T>
169         unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
170         void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
171         std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
172         Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
173         Message parse_message(std::string::iterator &, const std::string::iterator &) const;
174 };
175
176 } // namespace R2C2
177
178 #endif