X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fcontrol.cpp;h=ecf10348a7890a890bdc155b8ff66f04563baf14;hb=3e9c210ddc036cd015228504cc0803c909e27f84;hp=0ce16f088740524490e2f891b3d62561f588a309;hpb=06c100aacb559fbbe7380e15981c4772092c269b;p=r2c2.git diff --git a/source/libmarklin/control.cpp b/source/libmarklin/control.cpp index 0ce16f0..ecf1034 100644 --- a/source/libmarklin/control.cpp +++ b/source/libmarklin/control.cpp @@ -1,8 +1,15 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + #include #include #include #include -#include +#include #include #include #include "command.h" @@ -21,6 +28,17 @@ Control::Control(): debug(false) { } +Control::~Control() +{ + for(map::iterator i=sensors.begin(); i!=sensors.end(); ++i) + delete i->second; + for(map::iterator i=turnouts.begin(); i!=turnouts.end(); ++i) + 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; @@ -28,32 +46,13 @@ void Control::set_power(bool p) command(string(1, CMD_POWER_ON)); else command(string(1, CMD_POWER_OFF)); -} - -Turnout *Control::get_turnout(unsigned id) const -{ - TurnoutMap::const_iterator i=turnouts.find(id); - if(i!=turnouts.end()) - return i->second; - - return 0; -} -Locomotive *Control::get_locomotive(unsigned id) const -{ - for(LocomotiveSeq::const_iterator i=locomotives.begin(); i!=locomotives.end(); ++i) - if((*i)->get_address()==id) - return *i; - return 0; + signal_power_event.emit(power); } -Sensor *Control::get_sensor(unsigned id) const +void Control::set_debug(bool d) { - SensorMap::const_iterator i=sensors.find(id); - if(i!=sensors.end()) - return i->second; - - return 0; + debug=d; } void Control::open(const string &dev) @@ -104,8 +103,11 @@ void Control::open(const string &dev) break; } } + if(!ok) throw Exception("IB not detected"); + + command(string(1, CMD_STATUS)).signal_done.connect(sigc::mem_fun(this, &Control::status_done)); } Command &Control::command(const string &cmd) @@ -114,34 +116,61 @@ Command &Control::command(const string &cmd) return queue.back(); } -void Control::add_turnout(Turnout *t) +void Control::add_turnout(Turnout &t) +{ + turnouts[t.get_address()]=&t; +} + +Turnout &Control::get_turnout(unsigned id) const { - if(turnouts.count(t->get_address())==0) - turnouts.insert(TurnoutMap::value_type(t->get_address(), t)); + map::const_iterator i=turnouts.find(id); + if(i==turnouts.end()) + throw KeyError("Unknown turnout"); + + return *i->second; } -void Control::add_locomotive(Locomotive *l) +void Control::add_locomotive(Locomotive &l) { - if(find(locomotives.begin(), locomotives.end(), l)==locomotives.end()) - locomotives.push_back(l); + locomotives[l.get_address()]=&l; } -void Control::add_sensor(Sensor *s) +Locomotive &Control::get_locomotive(unsigned id) const { - if(sensors.count(s->get_address())==0) - { - sensors.insert(SensorMap::value_type(s->get_address(), s)); - poll_sensors=true; - } + map::const_iterator i=locomotives.find(id); + if(i==locomotives.end()) + throw KeyError("Unknown locomotive"); + + return *i->second; +} + +void Control::add_sensor(Sensor &s) +{ + sensors[s.get_address()]=&s; + poll_sensors=true; +} + +Sensor &Control::get_sensor(unsigned id) const +{ + map::const_iterator i=sensors.find(id); + if(i==sensors.end()) + throw KeyError("Unknown sensor"); + + return *i->second; } void Control::tick() { const Time::TimeStamp t=Time::now(); + for(map::const_iterator i=sensors.begin(); i!=sensors.end(); ++i) + i->second->tick(); + + timer.tick(false); + if(t>next_event_query) { - next_event_query=t+300*Time::msec; + next_event_query=t+200*Time::msec; command(string(1, CMD_EVENT)).signal_done.connect(sigc::mem_fun(this, &Control::event_query_done)); } @@ -157,28 +186,28 @@ void Control::tick() poll_sensors=false; } - if(queue.size() && queue.front().get_sent()) + if(!queue.empty() && queue.front().get_sent()) { pollfd pfd={serial_fd, POLLIN, 0}; if(poll(&pfd, 1, 0)>0) { - string resp=read_reply((Cmd)(unsigned char)queue.front().get_command()[0]); + string resp=read_reply(static_cast(static_cast(queue.front().get_command()[0]))); if(debug) { printf("read: "); for(unsigned i=0; i(resp[i])); printf("(%d bytes)\n", resp.size()); } - queue.front().signal_done.emit((Error)resp[0], resp.substr(1)); + queue.front().signal_done.emit(static_cast(resp[0]), resp.substr(1)); queue.erase(queue.begin()); } else return; } - if(queue.size()) + if(!queue.empty()) { string cmd=queue.front().get_command(); @@ -194,8 +223,8 @@ void Control::tick() { printf("write: "); for(unsigned i=0; i(cmd[i])); + printf("(%d bytes)\n", cmd.size()); } write(serial_fd, cmd.data(), cmd.size()); @@ -203,19 +232,11 @@ void Control::tick() } } -Control::~Control() +Time::Timer::Slot &Control::set_timer(const Time::TimeDelta &dt) { - for(SensorMap::iterator i=sensors.begin(); i!=sensors.end(); ++i) - delete i->second; - for(TurnoutMap::iterator i=turnouts.begin(); i!=turnouts.end(); ++i) - delete i->second; - for(LocomotiveSeq::iterator i=locomotives.begin(); i!=locomotives.end(); ++i) - delete *i; - close(serial_fd); + return timer.add(dt); } -/*** private ***/ - void Control::read_all(int fd, char *buf, int size) { int pos=0; @@ -274,6 +295,9 @@ string Control::read_reply(Cmd cmd) } else { + if(cmd==CMD_STATUS) + result+=ERR_NO_ERROR; + unsigned expected_bytes=1; if(cmd==CMD_FUNC_STATUS || cmd==CMD_TURNOUT_STATUS) expected_bytes=2; @@ -296,12 +320,20 @@ string Control::read_reply(Cmd cmd) return result; } +void Control::status_done(Error, const string &resp) +{ + power=((resp[0]&0x08)!=0); + signal_power_event.emit(power); +} + void Control::event_query_done(Error, const string &resp) { if(resp[0]&0x20) command(string(1, CMD_EVENT_TURNOUT)).signal_done.connect(sigc::mem_fun(this, &Control::turnout_event_done)); if(resp[0]&0x04) command(string(1, CMD_EVENT_SENSOR)).signal_done.connect(sigc::mem_fun(this, &Control::sensor_event_done)); + if(resp.size()>1 && (resp[1]&0x40)) + command(string(1, CMD_STATUS)).signal_done.connect(sigc::mem_fun(this, &Control::status_done)); } void Control::turnout_event_done(Error, const string &resp) @@ -309,7 +341,7 @@ void Control::turnout_event_done(Error, const string &resp) unsigned count=resp[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]); + cout<<"S88 module "<>(7-j%8))&1; - cout<>(7-j%8))&1); cout<<'\n'; + + for(unsigned j=0; j<16; ++j) + signal_sensor_event.emit(module*16+j-15, (resp[i+1+j/8]>>(7-j%8))&1); } }