// serial.cxx -- Unix serial I/O support // // Written by Curtis Olson, started November 1998. // // Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // 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., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id$ // (Log is kept at end of this file) #include #include #include #include #include #include #include "serial.hxx" fgSERIAL::fgSERIAL() { dev_open = false; } fgSERIAL::fgSERIAL(const string& device, int baud) { open_port(device); if ( dev_open ) { set_baud(baud); } } fgSERIAL::~fgSERIAL() { close(fd); } bool fgSERIAL::open_port(const string& device) { struct termios config; if ( (fd = open(device.c_str(), O_RDWR | O_NONBLOCK)) == -1 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Cannot open " << device << " for serial I/O" ); return false; } else { dev_open = true; } // set software flow control if ( tcgetattr( fd, &config ) != 0 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" ); return false; } config.c_iflag |= IXON; config.c_iflag |= IXOFF; if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" ); return false; } return true; } bool fgSERIAL::set_baud(int baud) { struct termios config; speed_t speed; if ( tcgetattr( fd, &config ) != 0 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" ); return false; } if ( baud == 300 ) { speed = B300; } else if ( baud == 1200 ) { speed = B1200; } else if ( baud == 2400 ) { speed = B2400; } else if ( baud == 4800 ) { speed = B4800; } else if ( baud == 9600 ) { speed = B9600; } else if ( baud == 19200 ) { speed = B19200; } else if ( baud == 38400 ) { speed = B38400; } else if ( baud == 57600 ) { speed = B57600; } else if ( baud == 115200 ) { speed = B115200; } else if ( baud == 230400 ) { speed = B230400; } else { FG_LOG( FG_SERIAL, FG_ALERT, "Unsupported baud rate " << baud ); return false; } if ( cfsetispeed( &config, speed ) != 0 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting input baud rate" ); return false; } if ( cfsetospeed( &config, speed ) != 0 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting output baud rate" ); return false; } if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) { FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" ); return false; } return true; } string fgSERIAL::read_port() { const int max_count = 1024; char buffer[max_count+1]; int count; string result; count = read(fd, buffer, max_count); // cout << "read " << count << " bytes" << endl; if ( count < 0 ) { // error condition if ( errno != EAGAIN ) { FG_LOG( FG_SERIAL, FG_ALERT, "Serial I/O on read, error number = " << errno ); } return ""; } else { buffer[count] = '\0'; result = buffer; return result; } } int fgSERIAL::write_port(const string& value) { int count; count = write(fd, value.c_str(), value.length()); // cout << "write '" << value << "' " << count << " bytes" << endl; if ( (int)count != (int)value.length() ) { FG_LOG( FG_SERIAL, FG_ALERT, "Serial I/O on write, error number = " << errno ); } return count; } // $Log$ // Revision 1.2 1998/11/19 03:35:43 curt // Updates ... // // Revision 1.1 1998/11/16 13:53:02 curt // Initial revision. //