]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/centralstation.h
Add driver for Märklin Central Station
[r2c2.git] / source / libr2c2 / centralstation.h
diff --git a/source/libr2c2/centralstation.h b/source/libr2c2/centralstation.h
new file mode 100644 (file)
index 0000000..ce5253b
--- /dev/null
@@ -0,0 +1,170 @@
+/* $Id$
+
+This file is part of R²C²
+Copyright © 2010  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef LIBR2C2_CENTRALSTATION_H_
+#define LIBR2C2_CENTRALSTATION_H_
+
+#include <msp/net/streamsocket.h>
+#include <msp/time/timestamp.h>
+#include "driver.h"
+
+namespace R2C2 {
+
+class CentralStation: public Driver
+{
+private:
+       struct Tag
+       {
+               std::string type;
+               unsigned code;
+               std::string value;
+
+               Tag();
+
+               operator bool() const;
+       };
+
+       struct Message
+       {
+               typedef std::map<std::string, std::string> AttribMap;
+               typedef std::map<unsigned, AttribMap> ObjectMap;
+       
+               Tag header;
+               ObjectMap content;
+               Tag footer;
+
+               operator bool() const;
+       };
+
+       enum Error
+       {
+               OK,
+               NERROR_UNKNOWNCOMMAND = 10,
+               NERROR_UNKNOWNARG = 11,
+               NERROR_UNKNOWNPARAM = 12,
+               NERROR_UNKNOWNID = 15,
+               NERROR_SIZE = 20,
+               NERROR_NOTALLOWED = 22,
+               NERROR_NOCONTROL = 25,
+               NERROR_NOCREATE = 28,
+               NERROR_NOARG = 29
+       };
+
+       enum Protocol
+       {
+               MM,
+               MM_27,
+               MFX
+       };
+
+       struct Locomotive
+       {
+               std::string name;
+               Protocol protocol;
+               unsigned address;
+               unsigned speed;
+               bool reverse;
+               unsigned funcs;
+               bool control;
+
+               Locomotive();
+       };
+
+       struct Turnout
+       {
+               enum Symbol
+               {
+                       LEFT,
+                       RIGHT,
+                       THREEWAY,
+                       DOUBLESLIP
+               };
+
+               unsigned address;
+               unsigned symbol;
+               unsigned state;
+               unsigned bits;
+               bool synced;
+
+               Turnout();
+       };
+
+       struct Sensor
+       {
+               bool state;
+               Msp::Time::TimeStamp off_timeout;
+
+               Sensor();
+       };
+
+       typedef std::map<unsigned, unsigned> AddressMap;
+       typedef std::map<unsigned, Locomotive> LocoMap;
+       typedef std::map<unsigned, Turnout> TurnoutMap;
+       typedef std::map<unsigned, Sensor> SensorMap;
+
+       Msp::Net::StreamSocket socket;
+       std::list<std::string> cmd_queue;
+       unsigned pending_commands;
+       bool power;
+       bool halted;
+       std::string in_buffer;
+       LocoMap locos;
+       AddressMap loco_addr;
+       bool locos_synced;
+       TurnoutMap turnouts;
+       AddressMap turnout_addr;
+       bool turnouts_synced;
+       SensorMap sensors;
+       std::vector<unsigned> s88;
+       bool sensors_synced;
+
+public:
+       CentralStation(const std::string &);
+       ~CentralStation();
+
+       virtual void set_power(bool);
+       virtual bool get_power() const { return power; }
+       virtual void halt(bool);
+       virtual bool is_halted() const { return halted; }
+
+       virtual const char *enumerate_protocols(unsigned) const;
+       virtual unsigned get_protocol_speed_steps(const std::string &) const;
+
+       virtual void add_loco(unsigned, const std::string &, const VehicleType &);
+       virtual void set_loco_speed(unsigned, unsigned);
+       virtual void set_loco_reverse(unsigned, bool);
+       virtual void set_loco_function(unsigned, unsigned, bool);
+
+       virtual void add_turnout(unsigned, const TrackType &);
+       virtual void set_turnout(unsigned, unsigned);
+       virtual unsigned get_turnout(unsigned) const;
+
+       virtual void add_sensor(unsigned);
+       virtual void set_sensor(unsigned, bool) { }
+       virtual bool get_sensor(unsigned) const;
+
+       virtual void tick();
+       virtual void flush();
+
+private:
+       void command(const std::string &, bool = false);
+       Message receive();
+       void process_reply(const Message &);
+       void process_event(const Message &);
+       void process_object(unsigned, const Message::AttribMap &);
+       Protocol map_protocol(const std::string &) const;
+       template<typename T>
+       unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
+       void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
+       std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
+       Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
+       Message parse_message(std::string::iterator &, const std::string::iterator &) const;
+};
+
+} // namespace R2C2
+
+#endif