]> git.mxchange.org Git - flightgear.git/blob - src/Network/ATC-Main.cxx
Remove unnecessary includes/using
[flightgear.git] / src / Network / ATC-Main.cxx
1 // ATC-Main.cxx -- FGFS interface to ATC hardware
2 //
3 // Written by Curtis Olson, started January 2002
4 //
5 // Copyright (C) 2002  Curtis L. Olson - http://www.flightgear.org/~curt
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include <simgear/compiler.h>
29
30 #include <stdlib.h>             // atoi() atof() abs()
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <errno.h>
35
36 #include <stdio.h>              //snprintf
37 #ifdef _WIN32
38 #  include <io.h>                 //lseek, read, write
39 #endif
40
41 #include <string>
42
43 #include <simgear/debug/logstream.hxx>
44 #include <simgear/props/props_io.hxx>
45 #include <simgear/io/iochannel.hxx>
46 #include <simgear/math/sg_types.hxx>
47 #include <simgear/misc/sg_path.hxx>
48 #include <simgear/props/props.hxx>
49 #include <simgear/structure/exception.hxx>
50
51 #include <Scripting/NasalSys.hxx>
52 #include <Main/fg_props.hxx>
53 #include <Main/globals.hxx>
54
55 #include "ATC-Main.hxx"
56
57 using std::string;
58 using std::cout;
59 using std::endl;
60 using std::vector;
61
62 // Lock the ATC hardware
63 static int fgATCMainLock( int fd ) {
64     // rewind
65     lseek( fd, 0, SEEK_SET );
66
67     char tmp[2];
68     int result = read( fd, tmp, 1 );
69     if ( result != 1 ) {
70         SG_LOG( SG_IO, SG_DEBUG, "Lock failed" );
71     }
72
73     return result;
74 }
75
76
77 // Write a radios command
78 static int fgATCMainRelease( int fd ) {
79     // rewind
80     lseek( fd, 0, SEEK_SET );
81
82     char tmp[2];
83     tmp[0] = tmp[1] = 0;
84     int result = write( fd, tmp, 1 );
85
86     if ( result != 1 ) {
87         SG_LOG( SG_IO, SG_DEBUG, "Release failed" );
88     }
89
90     return result;
91 }
92
93
94 void FGATCMain::init_config() {
95 #if defined( unix ) || defined( __CYGWIN__ )
96     // Next check home directory for .fgfsrc.hostname file
97     char *envp = ::getenv( "HOME" );
98     if ( envp != NULL ) {
99         SGPath atcsim_config( envp );
100         atcsim_config.append( ".fgfs-atc610x.xml" );
101         try {
102           SG_LOG(SG_NETWORK, SG_ALERT,
103                  "Warning: loading deprecated config file: " <<
104                  atcsim_config.str() );
105           readProperties( atcsim_config.str(), globals->get_props() );
106         } catch (const sg_exception &e) {
107           // fail silently, this is an old style config file I want to continue
108           // to support if it exists.
109         }
110     }
111 #endif
112 }
113
114
115 // Open and initialize ATC hardware
116 bool FGATCMain::open() {
117     if ( is_enabled() ) {
118         SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " 
119                 << "is already in use, ignoring" );
120         return false;
121     }
122
123     SG_LOG( SG_IO, SG_ALERT,
124             "Initializing ATC hardware, please wait ..." );
125
126     // This loads the config parameters generated by "simcal"
127     init_config();
128
129     /////////////////////////////////////////////////////////////////////
130     // Open the /proc files
131     /////////////////////////////////////////////////////////////////////
132
133     string lock0_file = "/proc/atcflightsim/board0/lock";
134     string lock1_file = "/proc/atcflightsim/board1/lock";
135
136     lock0_fd = ::open( lock0_file.c_str(), O_RDWR );
137     if ( lock0_fd == -1 ) {
138         SG_LOG( SG_IO, SG_ALERT, "errno = " << errno );
139         char msg[256];
140         snprintf( msg, 256, "Error opening %s", lock0_file.c_str() );
141         perror( msg );
142         exit( -1 );
143     }
144
145     lock1_fd = ::open( lock1_file.c_str(), O_RDWR );
146     if ( lock1_fd == -1 ) {
147         SG_LOG( SG_IO, SG_ALERT, "errno = " << errno );
148         char msg[256];
149         snprintf( msg, 256, "Error opening %s", lock1_file.c_str() );
150         perror( msg );
151         exit( -1 );
152     }
153
154     if ( input0_path.str().length() ) {
155         input0 = new FGATCInput( 0, input0_path );
156         input0->open();
157     }
158     if ( input1_path.str().length() ) {
159         input1 = new FGATCInput( 1, input1_path );
160         input1->open();
161     }
162     if ( output0_path.str().length() ) {
163         output0 = new FGATCOutput( 0, output0_path );
164         output0->open( lock0_fd );
165     }
166     if ( output1_path.str().length() ) {
167         output1 = new FGATCOutput( 1, output1_path );
168         output1->open( lock1_fd );
169     }
170
171     set_hz( 30 );               // default to processing requests @ 30Hz
172     set_enabled( true );
173
174     /////////////////////////////////////////////////////////////////////
175     // Finished initing hardware
176     /////////////////////////////////////////////////////////////////////
177
178     SG_LOG( SG_IO, SG_ALERT,
179             "Done initializing ATC hardware." );
180
181     return true;
182 }
183
184
185 bool FGATCMain::process() {
186     // cout << "Main::process()\n";
187
188     bool board0_locked = false;
189     bool board1_locked = false;
190
191     if ( input0 != NULL || output0 != NULL ) {
192         // Lock board0 if we have a configuration for it
193         if ( fgATCMainLock( lock0_fd ) > 0 ) {
194             board0_locked = true;
195         }
196     }
197
198     if ( input1 != NULL || output1 != NULL ) {
199         // Lock board1 if we have a configuration for it
200         if ( fgATCMainLock( lock1_fd ) > 0 ) {
201             board1_locked = true;
202         }
203     }
204
205     // cout << "  locks: ";
206     // if ( board0_locked ) { cout << "board0 "; }
207     // if ( board1_locked ) { cout << "board1 "; }
208     // cout << endl;
209
210     // process the ATC inputs
211     if ( input0 != NULL && board0_locked ) {
212         input0->process();
213     }
214     if ( input1 != NULL && board1_locked ) {
215         input1->process();
216     }
217
218     // run our custom nasal script.  This is a layer above the raw
219     // hardware inputs.  It handles situations where there isn't a
220     // direct 1-1 linear mapping between ATC functionality and FG
221     // functionality, and handles situations where FG expects more
222     // functionality from the interface than the ATC hardware can
223     // directly provide.
224
225     FGNasalSys *n = (FGNasalSys*)globals->get_subsystem("nasal");
226     bool result = n->parseAndRun( "atcsim.update()" );
227     if ( !result ) {
228         SG_LOG( SG_NETWORK, SG_ALERT, "Nasal: atcsim.update() failed!" );
229     }
230
231     // process the ATC outputs
232     if ( output0 != NULL && board0_locked ) {
233         output0->process();
234     }
235     if ( output1 != NULL && board1_locked ) {
236         output1->process();
237     }
238
239     if ( board0_locked ) {
240         fgATCMainRelease( lock0_fd );
241     }
242     if ( board1_locked ) {
243         fgATCMainRelease( lock1_fd );
244     }
245
246     return true;
247 }
248
249
250 bool FGATCMain::close() {
251     cout << "FGATCMain::close()" << endl;
252
253     int result;
254
255     if ( input0 != NULL ) {
256         input0->close();
257     }
258     if ( input1 != NULL ) {
259         input1->close();
260     }
261     if ( output0 != NULL ) {
262         output0->close();
263     }
264     if ( output1 != NULL ) {
265         output1->close();
266     }
267
268     result = ::close( lock0_fd );
269     if ( result == -1 ) {
270         SG_LOG( SG_IO, SG_ALERT, "errno = " << errno );
271         char msg[256];
272         snprintf( msg, 256, "Error closing lock0_fd" );
273         perror( msg );
274         exit( -1 );
275     }
276
277     result = ::close( lock1_fd );
278     if ( result == -1 ) {
279         SG_LOG( SG_IO, SG_ALERT, "errno = " << errno );
280         char msg[256];
281         snprintf( msg, 256, "Error closing lock1_fd" );
282         perror( msg );
283         exit( -1 );
284     }
285
286     return true;
287 }