X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fcontrol.cpp;h=ae26a179a9aa2f4b51585584b4d289ff6e59d4cc;hb=02c9a9779954d993cb73fe5f7a72b0847e87f633;hp=f51dbd09de45a61e171672bccc5ed3a139bca2f6;hpb=ca5b1fcfd52a09e3d3b2c4c011dc91ac9ad19694;p=r2c2.git diff --git a/source/libmarklin/control.cpp b/source/libmarklin/control.cpp index f51dbd0..ae26a17 100644 --- a/source/libmarklin/control.cpp +++ b/source/libmarklin/control.cpp @@ -1,12 +1,20 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2007-2009 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + #include #include #include -#include #include +#include #include #include #include "command.h" #include "control.h" +#include "reply.h" using namespace std; using namespace Msp; @@ -15,7 +23,6 @@ namespace Marklin { Control::Control(): serial_fd(-1), - p50_enabled(false), power(true), poll_sensors(false), debug(false) @@ -29,28 +36,13 @@ Control::~Control() delete i->second; for(map::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(string(1, CMD_POWER_ON)); - else - command(string(1, 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"); @@ -66,9 +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 ok = false; + bool p50 = false; for(unsigned i=0; baud[i]; i+=2) { cfsetospeed(&attr, baud[i+1]); @@ -76,47 +69,74 @@ 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 "<::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::const_iterator i=turnouts.find(id); + map::const_iterator i = turnouts.find(id); if(i==turnouts.end()) throw KeyError("Unknown turnout"); @@ -125,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::const_iterator i=locomotives.find(id); + map::const_iterator i = locomotives.find(id); if(i==locomotives.end()) throw KeyError("Unknown locomotive"); @@ -139,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::const_iterator i=sensors.find(id); + map::const_iterator i = sensors.find(id); if(i==sensors.end()) throw KeyError("Unknown sensor"); @@ -154,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::const_iterator i=sensors.begin(); i!=sensors.end(); ++i) i->second->tick(); @@ -163,37 +183,31 @@ void Control::tick() if(t>next_event_query) { - next_event_query=t+200*Time::msec; - command(string(1, CMD_EVENT)).signal_done.connect(sigc::mem_fun(this, &Control::event_query_done)); + 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())->second->get_address(); - string cmd(3, 0); - cmd[0]=CMD_SENSOR_PARAM_SET; - cmd[1]=0; - cmd[2]=(max_addr+7)/8; - command(cmd); - command(string(1, CMD_SENSOR_REPORT)); - poll_sensors=false; + unsigned max_addr = (--sensors.end())->first; + unsigned char data[2]; + data[0] = 0; + data[1] = (max_addr+7)/8; + command(CMD_SENSOR_PARAM_SET, data, 2); + command(CMD_SENSOR_REPORT); + 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) { - string resp=read_reply(static_cast(static_cast(queue.front().get_command()[0]))); + Reply reply = Reply::read(serial_fd, queue.front().get_command()); if(debug) - { - printf("read: "); - for(unsigned i=0; i(resp[i])); - printf("(%d bytes)\n", resp.size()); - } - - queue.front().signal_done.emit(static_cast(resp[0]), resp.substr(1)); + IO::print("R: %s\n", reply); + + queue.front().signal_done.emit(reply); queue.erase(queue.begin()); } else @@ -202,26 +216,17 @@ void Control::tick() if(!queue.empty()) { - string cmd=queue.front().get_command(); - - if(p50_enabled) - { - if(cmd[0]&0x80) - cmd="X"+cmd; - else - cmd="x"+cmd; - } - if(debug) + IO::print("W: %s\n", queue.front()); + + if(serial_fd>=0) + queue.front().send(serial_fd); + else { - printf("write: "); - for(unsigned i=0; i(cmd[i])); - printf("(%d bytes)\n", cmd.size()); + Reply reply = Reply::simulate(queue.front().get_command()); + queue.front().signal_done.emit(reply); + queue.erase(queue.begin()); } - - write(serial_fd, cmd.data(), cmd.size()); - queue.front().set_sent(true); } } @@ -230,130 +235,49 @@ Time::Timer::Slot &Control::set_timer(const Time::TimeDelta &dt) return timer.add(dt); } -void Control::read_all(int fd, char *buf, int size) +void Control::status_done(const Reply &reply) { - int pos=0; - while(pos1 && (resp[1]&0x40)) - command(string(1, CMD_STATUS)).signal_done.connect(sigc::mem_fun(this, &Control::status_done)); + 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[0]&0x80) && (data[1]&0x40)) + command(CMD_STATUS).signal_done.connect(sigc::mem_fun(this, &Control::status_done)); } -void Control::turnout_event_done(Error, const string &resp) +void Control::turnout_event_done(const Reply &reply) { - unsigned count=resp[0]; + const unsigned char *data = reply.get_data(); + unsigned count = data[0]; for(unsigned i=0; i(resp[i*2+1])+((resp[i*2+2]&7)<<8); - bool status=!(resp[i*2+2]&0x80); - cout<<"Turnout "<(resp[i]); + unsigned module = data[i]; - cout<<"S88 module "<>(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, (resp[i+1+j/8]>>(7-j%8))&1); + signal_sensor_event.emit(module*16+j-15, (data[i+1+j/8]>>(7-j%8))&1); } }