]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/control.cpp
Forgot to add the new files
[r2c2.git] / source / libmarklin / control.cpp
index 3eab42ce57b4e90aa0ac6840aeec242fcb1ec1e7..ae26a179a9aa2f4b51585584b4d289ff6e59d4cc 100644 (file)
@@ -1,15 +1,15 @@
 /* $Id$
 
 This file is part of the MSP Märklin suite
-Copyright © 2007-2008  Mikkosoft Productions, Mikko Rasa
+Copyright © 2007-2009  Mikkosoft Productions, Mikko Rasa
 Distributed under the GPL
 */
 
 #include <fcntl.h>
 #include <termios.h>
 #include <sys/poll.h>
-#include <iostream>
 #include <msp/core/except.h>
+#include <msp/io/print.h>
 #include <msp/time/units.h>
 #include <msp/time/utils.h>
 #include "command.h"
@@ -36,12 +36,13 @@ Control::~Control()
                delete i->second;
        for(map<unsigned, Locomotive *>::iterator i=locomotives.begin(); i!=locomotives.end(); ++i)
                delete i->second;
-       close(serial_fd);
+       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");
 
@@ -57,10 +58,10 @@ void Control::open(const string &dev)
        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]);
@@ -68,13 +69,13 @@ void Control::open(const string &dev)
 
                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";
+                       IO::print("IB detected at %d bits/s\n", baud[i]);
                        char buf[2];
-                       p50=(read(serial_fd, buf, 2)==2);
-                       ok=true;
+                       p50 = (read(serial_fd, buf, 2)==2);
+                       ok = true;
                        break;
                }
        }
@@ -90,12 +91,12 @@ void Control::open(const string &dev)
 
 void Control::set_debug(bool d)
 {
-       debug=d;
+       debug = d;
 }
 
 void Control::set_power(bool p)
 {
-       power=p;
+       power = p;
        if(power)
                command(CMD_POWER_ON);
        else
@@ -122,14 +123,20 @@ Command &Control::command(Cmd cmd, const unsigned char *data, unsigned len)
        return queue.back();
 }
 
+void Control::flush()
+{
+       for(list<Command>::iterator i=queue.begin(); i!=queue.end(); ++i)
+               i->send(serial_fd);
+}
+
 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");
 
@@ -138,12 +145,12 @@ Turnout &Control::get_turnout(unsigned id) const
 
 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");
 
@@ -152,13 +159,13 @@ Locomotive &Control::get_locomotive(unsigned id) const
 
 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");
 
@@ -167,7 +174,7 @@ Sensor &Control::get_sensor(unsigned id) const
 
 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();
@@ -176,29 +183,29 @@ void Control::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().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';
+                               IO::print("R: %s\n", reply);
 
                        queue.front().signal_done.emit(reply);
                        queue.erase(queue.begin());
@@ -210,9 +217,16 @@ void Control::tick()
        if(!queue.empty())
        {
                if(debug)
-                       cout<<"W: "<<queue.front()<<'\n';
+                       IO::print("W: %s\n", queue.front());
 
-               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());
+               }
        }
 }
 
@@ -223,47 +237,44 @@ Time::Timer::Slot &Control::set_timer(const Time::TimeDelta &dt)
 
 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);
-               cout<<"Turnout "<<addr<<", status "<<status<<'\n';
+               unsigned addr = (data[i*2+1])+((data[i*2+2]&7)<<8);
+               bool status = !(data[i*2+2]&0x80);
+               IO::print("Turnout %d, status %d\n", addr, status);
                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)
-                       cout<<((data[i+1+j/8]>>(7-j%8))&1);
-               cout<<'\n';
+               IO::print("S88 module %d, status %08b%08b\n", module, data[1], data[2]);
 
                for(unsigned j=0; j<16; ++j)
                        signal_sensor_event.emit(module*16+j-15, (data[i+1+j/8]>>(7-j%8))&1);