X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Fserial.cpp;h=09a9768023bad9e1fa00be0d398ac45a6933442c;hp=5d335b6faa82e0226c043d14ba3a158e8a84d8ae;hb=ea8bf8f588310b0d7fd3297d74907602705bba1d;hpb=d85465dd66a6fc80a9fb7868d1193a86abfe5b7c diff --git a/source/io/serial.cpp b/source/io/serial.cpp index 5d335b6..09a9768 100644 --- a/source/io/serial.cpp +++ b/source/io/serial.cpp @@ -1,151 +1,8 @@ -#ifdef WIN32 -#include -#else -#include -#include -#include -#endif -#include -#include -#include "handle_private.h" #include "serial.h" +#include "serial_private.h" using namespace std; -namespace { - -using namespace Msp; -using namespace Msp::IO; - -#ifdef WIN32 -typedef DCB DeviceState; -#else -typedef termios DeviceState; -#endif - -void get_state(const Handle &handle, DeviceState &state) -{ -#ifdef WIN32 - GetCommState(*handle, &state); -#else - tcgetattr(*handle, &state); -#endif -} - -void set_state(const Handle &handle, DeviceState &state) -{ -#ifdef WIN32 - if(SetCommState(*handle, &state)==0) - throw system_error("SetCommState"); -#else - if(tcsetattr(*handle, TCSADRAIN, &state)==-1) - throw system_error("tcsetattr"); -#endif -} - -void set_baud_rate(DeviceState &state, unsigned baud) -{ -#ifdef WIN32 - state.BaudRate = baud; -#else - speed_t speed; - switch(baud) - { - case 0: speed = B0; break; - case 50: speed = B50; break; - case 75: speed = B75; break; - case 110: speed = B110; break; - case 134: speed = B134; break; - case 150: speed = B150; break; - case 200: speed = B200; break; - case 300: speed = B300; break; - case 600: speed = B600; break; - case 1200: speed = B1200; break; - case 1800: speed = B1800; break; - case 2400: speed = B2400; break; - case 4800: speed = B4800; break; - case 9600: speed = B9600; break; - case 19200: speed = B19200; break; - case 38400: speed = B38400; break; - case 57600: speed = B57600; break; - case 115200: speed = B115200; break; - case 230400: speed = B230400; break; - default: throw invalid_argument("set_baud_rate"); - } - - cfsetospeed(&state, speed); - cfsetispeed(&state, speed); -#endif -} - -void set_data_bits(DeviceState &state, unsigned bits) -{ -#ifdef WIN32 - state.ByteSize = bits; -#else - tcflag_t flag; - switch(bits) - { - case 5: flag = CS5; break; - case 6: flag = CS6; break; - case 7: flag = CS7; break; - case 8: flag = CS8; break; - default: throw invalid_argument("set_data_bits"); - } - - state.c_cflag = (state.c_cflag&~CSIZE)|flag; -#endif -} - -void set_parity(DeviceState &state, Serial::Parity par) -{ -#ifdef WIN32 - switch(par) - { - case Serial::NONE: state.Parity = NOPARITY; break; - case Serial::EVEN: state.Parity = EVENPARITY; break; - case Serial::ODD: state.Parity = ODDPARITY; break; - default: throw invalid_argument("set_parity"); - } -#else - tcflag_t flag; - switch(par) - { - case Serial::NONE: flag = 0; break; - case Serial::EVEN: flag = PARENB; break; - case Serial::ODD: flag = PARENB|PARODD; break; - default: throw invalid_argument("set_parity"); - } - - state.c_cflag = (state.c_cflag&~(PARENB|PARODD))|flag; -#endif -} - -void set_stop_bits(DeviceState &state, unsigned bits) -{ -#ifdef WIN32 - switch(bits) - { - case 1: state.StopBits = ONESTOPBIT; break; - case 2: state.StopBits = TWOSTOPBITS; break; - default: throw invalid_argument("set_stop_bits"); - } -#else - tcflag_t flag; - switch(bits) - { - case 1: flag = 0; break; - case 2: flag = CSTOPB; break; - default: throw invalid_argument("set_stop_bits"); - } - - state.c_cflag = (state.c_cflag&~CSTOPB)|flag; -#endif -} - -} - - namespace Msp { namespace IO { @@ -155,36 +12,7 @@ Serial::Serial(const string &descr): string::size_type comma = descr.find(','); string port = descr.substr(0, comma); -#ifdef WIN32 - port = "\\\\.\\"+port; - - *handle = CreateFile(port.c_str(), GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if(!handle) - throw system_error(format("CreateFile(%s)", port)); - mode = M_READ|M_WRITE; - - COMMTIMEOUTS timeouts; - timeouts.ReadIntervalTimeout = MAXDWORD; - timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; - timeouts.ReadTotalTimeoutConstant = MAXDWORD-1; - timeouts.WriteTotalTimeoutMultiplier = 0; - timeouts.WriteTotalTimeoutConstant = 0; - SetCommTimeouts(*handle, &timeouts); -#else - if(port.compare(0, 5, "/dev/")) - port = "/dev/"+port; - - *handle = open(port.c_str(), O_RDWR); - if(!handle) - throw system_error(format("open(%s)", port)); - mode = M_READ|M_WRITE; - - termios t; - tcgetattr(*handle, &t); - t.c_lflag &= ~(ECHO|ICANON); - t.c_oflag &= ~OPOST; - tcsetattr(*handle, TCSADRAIN, &t); -#endif + platform_init(port); if(comma!=string::npos) { @@ -214,47 +42,46 @@ void Serial::close() void Serial::set_block(bool b) { - if(b) - mode = mode|M_NONBLOCK; - else - mode = mode&~M_NONBLOCK; + adjust_mode(mode, M_NONBLOCK, !b); + sys_set_blocking(handle, b); +} -#ifndef WIN32 - int flags = fcntl(*handle, F_GETFD); - fcntl(*handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); -#endif +void Serial::set_inherit(bool i) +{ + adjust_mode(mode, M_INHERIT, i); + sys_set_inherit(handle, i); } void Serial::set_baud_rate(unsigned rate) { DeviceState state; - get_state(handle, state); - ::set_baud_rate(state, rate); - set_state(handle, state); + state.get_from(handle); + state.set_baud_rate(rate); + state.apply_to(handle); } void Serial::set_data_bits(unsigned bits) { DeviceState state; - get_state(handle, state); - ::set_data_bits(state, bits); - set_state(handle, state); + state.get_from(handle); + state.set_data_bits(bits); + state.apply_to(handle); } void Serial::set_parity(Parity par) { DeviceState state; - get_state(handle, state); - ::set_parity(state, par); - set_state(handle, state); + state.get_from(handle); + state.set_parity(par); + state.apply_to(handle); } void Serial::set_stop_bits(unsigned bits) { DeviceState state; - get_state(handle, state); - ::set_stop_bits(state, bits); - set_state(handle, state); + state.get_from(handle); + state.set_stop_bits(bits); + state.apply_to(handle); } void Serial::set_parameters(const string ¶ms) @@ -271,12 +98,12 @@ void Serial::set_parameters(const string ¶ms) throw invalid_argument("Serial::set_parameters stop_bits"); DeviceState state; - get_state(handle, state); - ::set_baud_rate(state, lexical_cast(params.substr(0, i))); - ::set_data_bits(state, params[i+1]-'0'); - ::set_parity(state, (params[i+2]=='E' ? EVEN : params[i+2]=='O' ? ODD : NONE)); - ::set_stop_bits(state, params[i+3]-'0'); - set_state(handle, state); + state.get_from(handle); + state.set_baud_rate(lexical_cast(params.substr(0, i))); + state.set_data_bits(params[i+1]-'0'); + state.set_parity((params[i+2]=='E' ? EVEN : params[i+2]=='O' ? ODD : NONE)); + state.set_stop_bits(params[i+3]-'0'); + state.apply_to(handle); } unsigned Serial::do_write(const char *buf, unsigned size) @@ -292,7 +119,17 @@ unsigned Serial::do_read(char *buf, unsigned size) if(size==0) return 0; - return reader.read(buf, size); + unsigned ret = reader.read(buf, size); + if(ret==0) + set_eof(); + + return ret; +} + +const Handle &Serial::get_handle(Mode m) +{ + check_access(m); + return handle; } } // namespace IO