X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fcontrol.cpp;h=6c6ceb37da500e789d9a295ad68b1d0a53feb68f;hb=ae0600f7c3df5b6ef46992b1423888dd0e9a5026;hp=6e82614c21ebf904a65fd3d4d29b359bfe77c03e;hpb=aead7f2da831199fbb8f6950b067656b2965c2fa;p=r2c2.git diff --git a/source/libmarklin/control.cpp b/source/libmarklin/control.cpp index 6e82614..6c6ceb3 100644 --- a/source/libmarklin/control.cpp +++ b/source/libmarklin/control.cpp @@ -1,3 +1,10 @@ +/* $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 @@ -7,6 +14,7 @@ #include #include "command.h" #include "control.h" +#include "reply.h" using namespace std; using namespace Msp; @@ -15,19 +23,36 @@ namespace Marklin { Control::Control(): serial_fd(-1), - p50_enabled(false), power(true), poll_sensors(false), 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; if(power) - command(string(1, CMD_POWER_ON)); + command(CMD_POWER_ON); else - command(string(1, CMD_POWER_OFF)); + command(CMD_POWER_OFF); + + signal_power_event.emit(power); +} + +void Control::set_debug(bool d) +{ + debug=d; } void Control::open(const string &dev) @@ -51,6 +76,7 @@ void Control::open(const string &dev) attr.c_cflag|=CSTOPB; bool ok=false; + bool p50=false; for(unsigned i=0; baud[i]; i+=2) { cfsetospeed(&attr, baud[i+1]); @@ -61,30 +87,38 @@ void Control::open(const string &dev) pollfd pfd={serial_fd, POLLIN, 0}; if(poll(&pfd, 1, 500)>0) { - cout<<"IB detected at "<next_event_query) { - next_event_query=t+300*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)); + 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.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]); + Reply reply=Reply::read(serial_fd, queue.front().get_command()); if(debug) - { - printf("read: "); - for(unsigned i=0; i::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); -} - -/*** private ***/ - void Control::read_all(int fd, char *buf, int size) { int pos=0; @@ -232,109 +231,52 @@ void Control::read_all(int fd, char *buf, int size) } } -string Control::read_reply(Cmd cmd) +void Control::status_done(const Reply &reply) { - string result; - if(cmd==CMD_EVENT) - { - result+=ERR_NO_ERROR; - for(unsigned i=0; i<3; ++i) - { - char c; - read(serial_fd, &c, 1); - result+=c; - if(!(c&0x80)) break; - } - } - else if(cmd==CMD_EVENT_LOK) - { - result+=ERR_NO_ERROR; - char c[5]; - read(serial_fd, c+4, 1); - result+=c[4]; - while(c[4]&0x80) - { - read_all(serial_fd, c, 5); - result.append(c, 5); - } - } - else if(cmd==CMD_EVENT_TURNOUT) - { - result+=ERR_NO_ERROR; - char c[511]; - read(serial_fd, c, 1); - read_all(serial_fd, c+1, c[0]*2); - result.append(c, c[0]*2+1); - } - else if(cmd==CMD_EVENT_SENSOR) - { - result+=ERR_NO_ERROR; - char c[3]; - read(serial_fd, c+2, 1); - result+=c[2]; - while(c[2]) - { - read_all(serial_fd, c, 3); - result.append(c, 3); - } - } - else - { - unsigned expected_bytes=1; - if(cmd==CMD_FUNC_STATUS || cmd==CMD_TURNOUT_STATUS) - expected_bytes=2; - if(cmd==CMD_SENSOR_STATUS || cmd==CMD_TURNOUT_GROUP_STATUS) - expected_bytes=3; - if(cmd==CMD_LOK_STATUS) - expected_bytes=4; - if(cmd==CMD_LOK_CONFIG) - expected_bytes=5; - char c[5]; - read_all(serial_fd, c, 1); - result+=c[0]; - if(!c[0]) - { - read_all(serial_fd, c+1, expected_bytes-1); - result.append(c+1, expected_bytes-1); - } - } - - return result; + power=((reply.get_data()[0]&0x08)!=0); + signal_power_event.emit(power); } -void Control::event_query_done(Error, const string &resp) +void Control::event_query_done(const Reply &reply) { - 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)); + 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) + 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>(7-j%8))&1); + cout<<((data[i+1+j/8]>>(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); + signal_sensor_event.emit(module*16+j-15, (data[i+1+j/8]>>(7-j%8))&1); } }