]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/centralstation.h
Add driver for Märklin Central Station
[r2c2.git] / source / libr2c2 / centralstation.h
1 /* $Id$
2
3 This file is part of R²C²
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #ifndef LIBR2C2_CENTRALSTATION_H_
9 #define LIBR2C2_CENTRALSTATION_H_
10
11 #include <msp/net/streamsocket.h>
12 #include <msp/time/timestamp.h>
13 #include "driver.h"
14
15 namespace R2C2 {
16
17 class CentralStation: public Driver
18 {
19 private:
20         struct Tag
21         {
22                 std::string type;
23                 unsigned code;
24                 std::string value;
25
26                 Tag();
27
28                 operator bool() const;
29         };
30
31         struct Message
32         {
33                 typedef std::map<std::string, std::string> AttribMap;
34                 typedef std::map<unsigned, AttribMap> ObjectMap;
35         
36                 Tag header;
37                 ObjectMap content;
38                 Tag footer;
39
40                 operator bool() const;
41         };
42
43         enum Error
44         {
45                 OK,
46                 NERROR_UNKNOWNCOMMAND = 10,
47                 NERROR_UNKNOWNARG = 11,
48                 NERROR_UNKNOWNPARAM = 12,
49                 NERROR_UNKNOWNID = 15,
50                 NERROR_SIZE = 20,
51                 NERROR_NOTALLOWED = 22,
52                 NERROR_NOCONTROL = 25,
53                 NERROR_NOCREATE = 28,
54                 NERROR_NOARG = 29
55         };
56
57         enum Protocol
58         {
59                 MM,
60                 MM_27,
61                 MFX
62         };
63
64         struct Locomotive
65         {
66                 std::string name;
67                 Protocol protocol;
68                 unsigned address;
69                 unsigned speed;
70                 bool reverse;
71                 unsigned funcs;
72                 bool control;
73
74                 Locomotive();
75         };
76
77         struct Turnout
78         {
79                 enum Symbol
80                 {
81                         LEFT,
82                         RIGHT,
83                         THREEWAY,
84                         DOUBLESLIP
85                 };
86
87                 unsigned address;
88                 unsigned symbol;
89                 unsigned state;
90                 unsigned bits;
91                 bool synced;
92
93                 Turnout();
94         };
95
96         struct Sensor
97         {
98                 bool state;
99                 Msp::Time::TimeStamp off_timeout;
100
101                 Sensor();
102         };
103
104         typedef std::map<unsigned, unsigned> AddressMap;
105         typedef std::map<unsigned, Locomotive> LocoMap;
106         typedef std::map<unsigned, Turnout> TurnoutMap;
107         typedef std::map<unsigned, Sensor> SensorMap;
108
109         Msp::Net::StreamSocket socket;
110         std::list<std::string> cmd_queue;
111         unsigned pending_commands;
112         bool power;
113         bool halted;
114         std::string in_buffer;
115         LocoMap locos;
116         AddressMap loco_addr;
117         bool locos_synced;
118         TurnoutMap turnouts;
119         AddressMap turnout_addr;
120         bool turnouts_synced;
121         SensorMap sensors;
122         std::vector<unsigned> s88;
123         bool sensors_synced;
124
125 public:
126         CentralStation(const std::string &);
127         ~CentralStation();
128
129         virtual void set_power(bool);
130         virtual bool get_power() const { return power; }
131         virtual void halt(bool);
132         virtual bool is_halted() const { return halted; }
133
134         virtual const char *enumerate_protocols(unsigned) const;
135         virtual unsigned get_protocol_speed_steps(const std::string &) const;
136
137         virtual void add_loco(unsigned, const std::string &, const VehicleType &);
138         virtual void set_loco_speed(unsigned, unsigned);
139         virtual void set_loco_reverse(unsigned, bool);
140         virtual void set_loco_function(unsigned, unsigned, bool);
141
142         virtual void add_turnout(unsigned, const TrackType &);
143         virtual void set_turnout(unsigned, unsigned);
144         virtual unsigned get_turnout(unsigned) const;
145
146         virtual void add_sensor(unsigned);
147         virtual void set_sensor(unsigned, bool) { }
148         virtual bool get_sensor(unsigned) const;
149
150         virtual void tick();
151         virtual void flush();
152
153 private:
154         void command(const std::string &, bool = false);
155         Message receive();
156         void process_reply(const Message &);
157         void process_event(const Message &);
158         void process_object(unsigned, const Message::AttribMap &);
159         Protocol map_protocol(const std::string &) const;
160         template<typename T>
161         unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
162         void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
163         std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
164         Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
165         Message parse_message(std::string::iterator &, const std::string::iterator &) const;
166 };
167
168 } // namespace R2C2
169
170 #endif