]> git.mxchange.org Git - simgear.git/blob - Serial/serial.cxx
Cygnus tools compatibility tweaks.
[simgear.git] / Serial / serial.cxx
1 // serial.cxx -- Unix serial I/O support
2 //
3 // Written by Curtis Olson, started November 1998.
4 //
5 // Copyright (C) 1998  Curtis L. Olson - curt@flightgear.org
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22 // (Log is kept at end of this file)
23
24
25 #include <errno.h>
26 #include <termios.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include <Debug/logstream.hxx>
33
34 #include "serial.hxx"
35
36
37 fgSERIAL::fgSERIAL() {
38     dev_open = false;
39 }
40
41 fgSERIAL::fgSERIAL(const string& device, int baud) {
42     open_port(device);
43     
44     if ( dev_open ) {
45         set_baud(baud);
46     }
47 }
48
49 fgSERIAL::~fgSERIAL() {
50     close(fd);
51 }
52
53 bool fgSERIAL::open_port(const string& device) {
54     struct termios config;
55
56     if ( (fd = open(device.c_str(), O_RDWR | O_NONBLOCK)) == -1 ) {
57         FG_LOG( FG_SERIAL, FG_ALERT, "Cannot open " << device
58                 << " for serial I/O" );
59         return false;
60     } else {
61         dev_open = true;
62     }
63
64     // set required port parameters 
65     if ( tcgetattr( fd, &config ) != 0 ) {
66         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
67         return false;
68     }
69
70     cfmakeraw( &config );
71
72     // cout << "config.c_iflag = " << config.c_iflag << endl;
73
74     // software flow control on
75     // config.c_iflag |= IXON;
76     // config.c_iflag |= IXOFF;
77
78     // disable hardware flow control
79     // config.c_cflag |= CRTSCTS;
80
81     // cout << "config.c_iflag = " << config.c_iflag << endl;
82
83     if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
84         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
85         return false;
86     }
87
88     return true;
89 }
90
91 bool fgSERIAL::set_baud(int baud) {
92     struct termios config;
93     speed_t speed = B9600;
94
95     if ( tcgetattr( fd, &config ) != 0 ) {
96         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
97         return false;
98     }
99
100     if ( baud == 300 ) {
101         speed = B300;
102     } else if ( baud == 1200 ) {
103         speed = B1200;
104     } else if ( baud == 2400 ) {
105         speed = B2400;
106     } else if ( baud == 4800 ) {
107         speed = B4800;
108     } else if ( baud == 9600 ) {
109         speed = B9600;
110     } else if ( baud == 19200 ) {
111         speed = B19200;
112     } else if ( baud == 38400 ) {
113         speed = B38400;
114     } else if ( baud == 57600 ) {
115         speed = B57600;
116     } else if ( baud == 115200 ) {
117         speed = B115200;
118 #if defined( linux ) || defined( __FreeBSD__ )
119     } else if ( baud == 230400 ) {
120         speed = B230400;
121 #endif
122     } else {
123         FG_LOG( FG_SERIAL, FG_ALERT, "Unsupported baud rate " << baud );
124         return false;
125     }
126
127     if ( cfsetispeed( &config, speed ) != 0 ) {
128         FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting input baud rate" );
129         return false;
130     }
131
132     if ( cfsetospeed( &config, speed ) != 0 ) {
133         FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting output baud rate" );
134         return false;
135     }
136
137     if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
138         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
139         return false;
140     }
141
142     return true;
143 }
144
145 string fgSERIAL::read_port() {
146     const int max_count = 1024;
147     char buffer[max_count+1];
148     int count;
149     string result;
150
151     count = read(fd, buffer, max_count);
152     // cout << "read " << count << " bytes" << endl;
153
154     if ( count < 0 ) {
155         // error condition
156         if ( errno != EAGAIN ) {
157             FG_LOG( FG_SERIAL, FG_ALERT, 
158                     "Serial I/O on read, error number = " << errno );
159         }
160
161         return "";
162     } else {
163         buffer[count] = '\0';
164         result = buffer;
165
166         return result;
167     }
168 }
169
170 int fgSERIAL::write_port(const string& value) {
171     int count;
172
173     count = write(fd, value.c_str(), value.length());
174     // cout << "write '" << value << "'  " << count << " bytes" << endl;
175
176     if ( (int)count != (int)value.length() ) {
177         FG_LOG( FG_SERIAL, FG_ALERT,
178                 "Serial I/O on write, error number = " << errno );
179     }
180
181     return count;
182 }
183
184
185 // $Log$
186 // Revision 1.4  1998/11/23 21:47:00  curt
187 // Cygnus tools compatibility tweaks.
188 //
189 // Revision 1.3  1998/11/19 13:52:54  curt
190 // port configuration tweaks & experiments.
191 //
192 // Revision 1.2  1998/11/19 03:35:43  curt
193 // Updates ...
194 //
195 // Revision 1.1  1998/11/16 13:53:02  curt
196 // Initial revision.
197 //