X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fserial%2Fserial.cxx;h=985cc8755e47c4761a2feafb83b0f471c3010896;hb=08fb4339236536be2a31768d03d9826d1491437d;hp=aca930a6136e25a03821a5a943fc89b4c7cdd416;hpb=b3f88735a88ab60089298ef299a99ca650536a86;p=simgear.git diff --git a/simgear/serial/serial.cxx b/simgear/serial/serial.cxx index aca930a6..985cc875 100644 --- a/simgear/serial/serial.cxx +++ b/simgear/serial/serial.cxx @@ -2,7 +2,7 @@ // // Written by Curtis Olson, started November 1998. // -// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -14,27 +14,19 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ #include -#include STL_IOSTREAM +#include +#include -#ifdef SG_HAVE_STD_INCLUDE -# include -#else -# include -#endif - -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) - // maybe include something??? -#else +#ifndef _WIN32 # include # include # include @@ -68,14 +60,14 @@ SGSerialPort::~SGSerialPort() { bool SGSerialPort::open_port(const string& device) { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) +#ifdef _WIN32 fd = CreateFile( device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, // dwShareMode NULL, // lpSecurityAttributes OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, + 0, NULL ); if ( fd == INVALID_HANDLE_VALUE ) { @@ -104,7 +96,7 @@ bool SGSerialPort::open_port(const string& device) { struct termios config; - fd = open(device.c_str(), O_RDWR | O_NONBLOCK); + fd = open(device.c_str(), O_RDWR | O_NOCTTY| O_NDELAY); SG_LOG( SG_EVENT, SG_DEBUG, "Serial fd created = " << fd); if ( fd == -1 ) { @@ -125,18 +117,24 @@ bool SGSerialPort::open_port(const string& device) { // cout << "config.c_iflag = " << config.c_iflag << endl; - // software flow control on - config.c_iflag |= IXON; - // config.c_iflag |= IXOFF; + // disable LF expanded to CR-LF + config.c_oflag &= ~(ONLCR); + + // disable software flow control + config.c_iflag &= ~(IXON | IXOFF | IXANY); - // config.c_cflag |= CLOCAL; + // enable the receiver and set local mode + config.c_cflag |= (CLOCAL | CREAD); -#if ! defined( sgi ) +#if !defined( sgi ) && !defined(_AIX) // disable hardware flow control config.c_cflag &= ~(CRTSCTS); #endif // cout << "config.c_iflag = " << config.c_iflag << endl; + + // Raw (not cooked/canonical) input mode + config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) { SG_LOG( SG_IO, SG_ALERT, "Unable to update port settings" ); @@ -149,7 +147,7 @@ bool SGSerialPort::open_port(const string& device) { bool SGSerialPort::close_port() { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) +#ifdef _WIN32 CloseHandle( fd ); #else close(fd); @@ -163,7 +161,52 @@ bool SGSerialPort::close_port() { bool SGSerialPort::set_baud(int baud) { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) +#ifdef _WIN32 + + DCB dcb; + if ( GetCommState( fd, &dcb ) ) { + dcb.BaudRate = baud; + dcb.fOutxCtsFlow = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fOutX = TRUE; + dcb.fInX = TRUE; + + if ( !SetCommState( fd, &dcb ) ) { + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + SG_LOG( SG_IO, SG_ALERT, "Unable to update port settings: " + << (const char*) lpMsgBuf ); + LocalFree( lpMsgBuf ); + return false; + } + } else { + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + SG_LOG( SG_IO, SG_ALERT, "Unable to poll port settings: " + << (const char*) lpMsgBuf ); + LocalFree( lpMsgBuf ); + return false; + } return true; @@ -191,11 +234,11 @@ bool SGSerialPort::set_baud(int baud) { speed = B19200; } else if ( baud == 38400 ) { speed = B38400; +#if defined( linux ) || defined( __FreeBSD__ ) } else if ( baud == 57600 ) { speed = B57600; } else if ( baud == 115200 ) { speed = B115200; -#if defined( linux ) || defined( __FreeBSD__ ) } else if ( baud == 230400 ) { speed = B230400; #endif @@ -227,19 +270,39 @@ bool SGSerialPort::set_baud(int baud) { string SGSerialPort::read_port() { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) + const int max_count = 1024; + char buffer[max_count+1]; + string result; + +#ifdef _WIN32 + + DWORD count; + if ( ReadFile( fd, buffer, max_count, &count, 0 ) ) { + buffer[count] = '\0'; + result = buffer; + } else { + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + SG_LOG( SG_IO, SG_ALERT, "Serial I/O read error: " + << (const char*) lpMsgBuf ); + LocalFree( lpMsgBuf ); + } - string result = ""; return result; #else - const int max_count = 1024; - char buffer[max_count+1]; - int count; - string result; - - count = read(fd, buffer, max_count); + int count = read(fd, buffer, max_count); // cout << "read " << count << " bytes" << endl; if ( count < 0 ) { @@ -263,10 +326,33 @@ string SGSerialPort::read_port() { int SGSerialPort::read_port(char *buf, int len) { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) +#ifdef _WIN32 + + DWORD count; + if ( ReadFile( fd, buf, len, &count, 0 ) ) { + buf[count] = '\0'; + + return count; + } else { + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); - buf[0] = '\0'; - return 0; + SG_LOG( SG_IO, SG_ALERT, "Serial I/O read error: " + << (const char*) lpMsgBuf ); + LocalFree( lpMsgBuf ); + + buf[0] = '\0'; + return 0; + } #else @@ -297,18 +383,17 @@ int SGSerialPort::read_port(char *buf, int len) { int SGSerialPort::write_port(const string& value) { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) +#ifdef _WIN32 - LPCVOID lpBuffer = value.c_str(); + LPCVOID lpBuffer = value.data(); DWORD nNumberOfBytesToWrite = value.length(); DWORD lpNumberOfBytesWritten; - OVERLAPPED lpOverlapped; if ( WriteFile( fd, lpBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, - &lpOverlapped ) == 0 ) + 0 ) == 0 ) { LPVOID lpMsgBuf; FormatMessage( @@ -372,18 +457,17 @@ int SGSerialPort::write_port(const string& value) { int SGSerialPort::write_port(const char* buf, int len) { -#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) +#ifdef _WIN32 LPCVOID lpBuffer = buf; DWORD nNumberOfBytesToWrite = len; DWORD lpNumberOfBytesWritten; - OVERLAPPED lpOverlapped; if ( WriteFile( fd, lpBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, - &lpOverlapped ) == 0 ) + 0 ) == 0 ) { LPVOID lpMsgBuf; FormatMessage(