/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2007-2009 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
delete i->second;
for(map<unsigned, Locomotive *>::iterator i=locomotives.begin(); i!=locomotives.end(); ++i)
delete i->second;
- close(serial_fd);
-}
-
-void Control::set_power(bool p)
-{
- power=p;
- if(power)
- command(CMD_POWER_ON);
- else
- command(CMD_POWER_OFF);
-
- signal_power_event.emit(power);
-}
-
-void Control::set_debug(bool d)
-{
- debug=d;
+ if(serial_fd>=0)
+ close(serial_fd);
}
void Control::open(const string &dev)
{
- serial_fd=::open(dev.c_str(), O_RDWR);
+ serial_fd = ::open(dev.c_str(), O_RDWR);
if(serial_fd<0)
throw Exception("Couldn't open serial port\n");
termios attr;
tcgetattr(serial_fd, &attr);
cfmakeraw(&attr);
- attr.c_cflag|=CSTOPB;
+ attr.c_cflag |= CSTOPB;
- bool ok=false;
- bool p50=false;
+ bool ok = false;
+ bool p50 = false;
for(unsigned i=0; baud[i]; i+=2)
{
cfsetospeed(&attr, baud[i+1]);
write(serial_fd, "\xC4", 1);
- pollfd pfd={serial_fd, POLLIN, 0};
+ pollfd pfd = { serial_fd, POLLIN, 0 };
if(poll(&pfd, 1, 500)>0)
{
cout<<"IB detected at "<<baud[i]<<" bits/s\n";
char buf[2];
- p50=(read(serial_fd, buf, 2)==2);
- ok=true;
+ p50 = (read(serial_fd, buf, 2)==2);
+ ok = true;
break;
}
}
command(CMD_STATUS).signal_done.connect(sigc::mem_fun(this, &Control::status_done));
}
+void Control::set_debug(bool d)
+{
+ debug = d;
+}
+
+void Control::set_power(bool p)
+{
+ power = p;
+ if(power)
+ command(CMD_POWER_ON);
+ else
+ command(CMD_POWER_OFF);
+
+ signal_power_event.emit(power);
+}
+
Command &Control::command(Cmd cmd)
{
queue.push_back(Command(cmd, 0, 0));
void Control::add_turnout(Turnout &t)
{
- turnouts[t.get_address()]=&t;
+ turnouts[t.get_address()] = &t;
}
Turnout &Control::get_turnout(unsigned id) const
{
- map<unsigned, Turnout *>::const_iterator i=turnouts.find(id);
+ map<unsigned, Turnout *>::const_iterator i = turnouts.find(id);
if(i==turnouts.end())
throw KeyError("Unknown turnout");
void Control::add_locomotive(Locomotive &l)
{
- locomotives[l.get_address()]=&l;
+ locomotives[l.get_address()] = &l;
}
Locomotive &Control::get_locomotive(unsigned id) const
{
- map<unsigned, Locomotive *>::const_iterator i=locomotives.find(id);
+ map<unsigned, Locomotive *>::const_iterator i = locomotives.find(id);
if(i==locomotives.end())
throw KeyError("Unknown locomotive");
void Control::add_sensor(Sensor &s)
{
- sensors[s.get_address()]=&s;
- poll_sensors=true;
+ sensors[s.get_address()] = &s;
+ poll_sensors = true;
}
Sensor &Control::get_sensor(unsigned id) const
{
- map<unsigned, Sensor *>::const_iterator i=sensors.find(id);
+ map<unsigned, Sensor *>::const_iterator i = sensors.find(id);
if(i==sensors.end())
throw KeyError("Unknown sensor");
void Control::tick()
{
- const Time::TimeStamp t=Time::now();
+ const Time::TimeStamp t = Time::now();
for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
i->second->tick();
if(t>next_event_query)
{
- next_event_query=t+200*Time::msec;
+ next_event_query = t+200*Time::msec;
command(CMD_EVENT).signal_done.connect(sigc::mem_fun(this, &Control::event_query_done));
}
if(poll_sensors)
{
- unsigned max_addr=(--sensors.end())->first;
+ unsigned max_addr = (--sensors.end())->first;
unsigned char data[2];
- data[0]=0;
- data[1]=(max_addr+7)/8;
+ data[0] = 0;
+ data[1] = (max_addr+7)/8;
command(CMD_SENSOR_PARAM_SET, data, 2);
command(CMD_SENSOR_REPORT);
- poll_sensors=false;
+ poll_sensors = false;
}
- if(!queue.empty() && queue.front().get_sent())
+ if(!queue.empty() && queue.front().is_sent())
{
- pollfd pfd={serial_fd, POLLIN, 0};
+ pollfd pfd = { serial_fd, POLLIN, 0 };
if(poll(&pfd, 1, 0)>0)
{
- Reply reply=Reply::read(serial_fd, queue.front().get_command());
+ Reply reply = Reply::read(serial_fd, queue.front().get_command());
if(debug)
cout<<"R: "<<reply<<'\n';
if(debug)
cout<<"W: "<<queue.front()<<'\n';
- queue.front().send(serial_fd);
+ if(serial_fd>=0)
+ queue.front().send(serial_fd);
+ else
+ {
+ Reply reply = Reply::simulate(queue.front().get_command());
+ queue.front().signal_done.emit(reply);
+ queue.erase(queue.begin());
+ }
}
}
return timer.add(dt);
}
-void Control::read_all(int fd, char *buf, int size)
-{
- int pos=0;
- while(pos<size)
- {
- int len=read(fd, buf+pos, size-pos);
- pos+=len;
- }
-}
-
void Control::status_done(const Reply &reply)
{
- power=((reply.get_data()[0]&0x08)!=0);
+ power = ((reply.get_data()[0]&0x08)!=0);
signal_power_event.emit(power);
}
void Control::event_query_done(const Reply &reply)
{
- const unsigned char *data=reply.get_data();
+ const unsigned char *data = reply.get_data();
if(data[0]&0x01)
command(CMD_EVENT_LOK);
if(data[0]&0x20)
command(CMD_EVENT_TURNOUT).signal_done.connect(sigc::mem_fun(this, &Control::turnout_event_done));
if(data[0]&0x04)
command(CMD_EVENT_SENSOR).signal_done.connect(sigc::mem_fun(this, &Control::sensor_event_done));
- if(data[1]&0x40)
+ if((data[0]&0x80) && (data[1]&0x40))
command(CMD_STATUS).signal_done.connect(sigc::mem_fun(this, &Control::status_done));
}
void Control::turnout_event_done(const Reply &reply)
{
- const unsigned char *data=reply.get_data();
- unsigned count=data[0];
+ const unsigned char *data = reply.get_data();
+ unsigned count = data[0];
for(unsigned i=0; i<count; ++i)
{
- unsigned addr=(data[i*2+1])+((data[i*2+2]&7)<<8);
- bool status=!(data[i*2+2]&0x80);
+ unsigned addr = (data[i*2+1])+((data[i*2+2]&7)<<8);
+ bool status = !(data[i*2+2]&0x80);
cout<<"Turnout "<<addr<<", status "<<status<<'\n';
signal_turnout_event.emit(addr, status);
}
void Control::sensor_event_done(const Reply &reply)
{
- const unsigned char *data=reply.get_data();
+ const unsigned char *data = reply.get_data();
for(unsigned i=0; data[i]; i+=3)
{
- unsigned module=data[i];
+ unsigned module = data[i];
cout<<"S88 module "<<module<<", status ";
for(unsigned j=0; j<16; ++j)