]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/intellibox.h
Fix a segfault in removing vehicles when creating a new train
[r2c2.git] / source / libmarklin / intellibox.h
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #ifndef LIBMARKLIN_INTELLIBOX_H_
9 #define LIBMARKLIN_INTELLIBOX_H_
10
11 #include <map>
12 #include <msp/time/timestamp.h>
13 #include "driver.h"
14
15 namespace Marklin {
16
17 class Intellibox: public Driver
18 {
19 private:
20         enum Command
21         {
22                 CMD_LOK=0x80,
23                 CMD_LOK_STATUS=0x84,
24                 CMD_LOK_CONFIG=0x85,
25                 CMD_FUNC=0x88,
26                 CMD_FUNC_STATUS=0x8C,
27                 CMD_TURNOUT=0x90,
28                 CMD_TURNOUT_FREE=0x93,
29                 CMD_TURNOUT_STATUS=0x94,
30                 CMD_TURNOUT_GROUP_STATUS=0x95,
31                 CMD_SENSOR_STATUS=0x98,
32                 CMD_SENSOR_REPORT=0x99,
33                 CMD_SENSOR_PARAM_SET=0x9D,
34                 CMD_STATUS=0xA2,
35                 CMD_POWER_OFF=0xA6,
36                 CMD_POWER_ON=0xA7,
37                 CMD_NOP=0xC4,
38                 CMD_EVENT=0xC8,
39                 CMD_EVENT_LOK=0xC9,
40                 CMD_EVENT_TURNOUT=0xCA,
41                 CMD_EVENT_SENSOR=0xCB
42         };
43
44         enum Error
45         {
46                 ERR_NO_ERROR=0,
47                 ERR_SYS_ERROR,
48                 ERR_BAD_PARAM,
49                 ERR_POWER_OFF=0x6,
50                 ERR_NO_LOK_SPACE=0x8,  // No space in lok command buffer
51                 ERR_NO_TURNOUT_SPACE,  // No space in turnout command buffer
52                 ERR_NO_DATA,           // "no Lok status available (Lok is not in a slot)"
53                 ERR_NO_SLOT,           // "there is no slot available"
54                 ERR_BAD_LOK_ADDR,
55                 ERR_LOK_BUSY,
56                 ERR_BAD_TURNOUT_ADDR,
57                 ERR_BAD_SO_VALUE,
58                 ERR_NO_I2C_SPACE,
59                 ERR_LOW_TURNOUT_SPACE=0x40,
60                 ERR_LOK_HALTED,
61                 ERR_LOK_POWER_OFF,
62         };
63
64         struct Locomotive
65         {
66                 std::string protocol;
67                 unsigned speed;
68                 bool reverse;
69                 unsigned funcs;
70
71                 Locomotive();
72         };
73
74         struct Turnout
75         {
76                 bool state;
77                 bool active;
78                 bool pending;
79                 Msp::Time::TimeStamp off_timeout;
80
81                 Turnout();
82         };
83
84         struct Sensor
85         {
86                 bool state;
87                 Msp::Time::TimeStamp off_timeout;
88
89                 Sensor();
90         };
91
92         struct CommandSlot
93         {
94                 Command cmd;
95                 unsigned addr;
96                 unsigned char data[8];
97                 unsigned length;
98         };
99
100         int serial_fd;
101         bool power;
102         bool halted;
103         std::map<unsigned, Locomotive> locos;
104         std::map<unsigned, Turnout> turnouts;
105         std::map<unsigned, Sensor> sensors;
106         bool update_sensors;
107         std::list<CommandSlot> queue;
108         bool command_sent;
109         Msp::Time::TimeStamp next_event_query;
110
111 public:
112         Intellibox(const std::string &);
113
114         virtual void set_power(bool);
115         virtual bool get_power() const { return power; }
116         virtual void halt(bool);
117         virtual bool is_halted() const { return halted; }
118
119         virtual const char *enumerate_protocols(unsigned) const;
120         virtual unsigned get_protocol_speed_steps(const std::string &) const;
121         virtual void add_loco(unsigned, const std::string &);
122         virtual void set_loco_speed(unsigned, unsigned);
123         virtual void set_loco_reverse(unsigned, bool);
124         virtual void set_loco_function(unsigned, unsigned, bool);
125
126         virtual void add_turnout(unsigned);
127         virtual void set_turnout(unsigned, bool);
128         virtual bool get_turnout(unsigned) const;
129
130         virtual void add_sensor(unsigned);
131         virtual void set_sensor(unsigned, bool) { }
132         virtual bool get_sensor(unsigned) const;
133
134         virtual void tick();
135         virtual void flush();
136
137 private:
138         void command(Command);
139         void command(Command, const unsigned char *, unsigned);
140         void command(Command, unsigned, const unsigned char *, unsigned);
141         void loco_command(unsigned, unsigned, bool, unsigned);
142         void turnout_command(unsigned, bool, bool);
143         void process_reply(const Msp::Time::TimeStamp &);
144         unsigned read_all(unsigned char *, unsigned);
145         unsigned read_status(Error *);
146         void error(Command, Error);
147 };
148
149 } // namespace Marklin
150
151 #endif