]> git.mxchange.org Git - simgear.git/blob - Serial/serial.cxx
FreeBSD support.
[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 <termios.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30
31 #include <Debug/logstream.hxx>
32
33 #include "serial.hxx"
34
35
36 fgSERIAL::fgSERIAL() {
37     dev_open = false;
38 }
39
40 fgSERIAL::fgSERIAL(const string& device, int baud) {
41     open_port(device);
42     
43     if ( dev_open ) {
44         set_baud(baud);
45     }
46 }
47
48 fgSERIAL::~fgSERIAL() {
49     close(fd);
50 }
51
52 bool fgSERIAL::open_port(const string& device) {
53     struct termios config;
54
55     if ( (fd = open(device.c_str(), O_RDWR | O_NONBLOCK)) == -1 ) {
56         FG_LOG( FG_SERIAL, FG_ALERT, "Cannot open " << device
57                 << " for serial I/O" );
58         return false;
59     } else {
60         dev_open = true;
61     }
62
63     // set required port parameters 
64     if ( tcgetattr( fd, &config ) != 0 ) {
65         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
66         return false;
67     }
68
69     cfmakeraw( &config );
70
71     // cout << "config.c_iflag = " << config.c_iflag << endl;
72
73     // software flow control on
74     // config.c_iflag |= IXON;
75     // config.c_iflag |= IXOFF;
76
77     // disable hardware flow control
78     // config.c_cflag |= CRTSCTS;
79
80     // cout << "config.c_iflag = " << config.c_iflag << endl;
81
82     if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
83         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
84         return false;
85     }
86
87     return true;
88 }
89
90 bool fgSERIAL::set_baud(int baud) {
91     struct termios config;
92     speed_t speed;
93
94     if ( tcgetattr( fd, &config ) != 0 ) {
95         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
96         return false;
97     }
98
99     if ( baud == 300 ) {
100         speed = B300;
101     } else if ( baud == 1200 ) {
102         speed = B1200;
103     } else if ( baud == 2400 ) {
104         speed = B2400;
105     } else if ( baud == 4800 ) {
106         speed = B4800;
107     } else if ( baud == 9600 ) {
108         speed = B9600;
109     } else if ( baud == 19200 ) {
110         speed = B19200;
111     } else if ( baud == 38400 ) {
112         speed = B38400;
113     } else if ( baud == 57600 ) {
114         speed = B57600;
115     } else if ( baud == 115200 ) {
116         speed = B115200;
117     } else if ( baud == 230400 ) {
118         speed = B230400;
119     } else {
120         FG_LOG( FG_SERIAL, FG_ALERT, "Unsupported baud rate " << baud );
121         return false;
122     }
123
124     if ( cfsetispeed( &config, speed ) != 0 ) {
125         FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting input baud rate" );
126         return false;
127     }
128
129     if ( cfsetospeed( &config, speed ) != 0 ) {
130         FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting output baud rate" );
131         return false;
132     }
133
134     if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
135         FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
136         return false;
137     }
138
139     return true;
140 }
141
142 string fgSERIAL::read_port() {
143     const int max_count = 1024;
144     char buffer[max_count+1];
145     int count;
146     string result;
147
148     count = read(fd, buffer, max_count);
149     // cout << "read " << count << " bytes" << endl;
150
151     if ( count < 0 ) {
152         // error condition
153         if ( errno != EAGAIN ) {
154             FG_LOG( FG_SERIAL, FG_ALERT, 
155                     "Serial I/O on read, error number = " << errno );
156         }
157
158         return "";
159     } else {
160         buffer[count] = '\0';
161         result = buffer;
162
163         return result;
164     }
165 }
166
167 int fgSERIAL::write_port(const string& value) {
168     int count;
169
170     count = write(fd, value.c_str(), value.length());
171     // cout << "write '" << value << "'  " << count << " bytes" << endl;
172
173     if ( (int)count != (int)value.length() ) {
174         FG_LOG( FG_SERIAL, FG_ALERT,
175                 "Serial I/O on write, error number = " << errno );
176     }
177
178     return count;
179 }
180
181
182 // $Log$
183 // Revision 1.3  1998/11/19 13:52:54  curt
184 // port configuration tweaks & experiments.
185 //
186 // Revision 1.2  1998/11/19 03:35:43  curt
187 // Updates ...
188 //
189 // Revision 1.1  1998/11/16 13:53:02  curt
190 // Initial revision.
191 //