From d25ab417c5e9de5ac376b79f8f7c4b5b838b0c37 Mon Sep 17 00:00:00 2001 From: curt Date: Wed, 25 Nov 1998 01:33:58 +0000 Subject: [PATCH] Support for an arbitrary number of serial ports. --- Main/fg_serial.cxx | 204 ++++++++++++++++++++++++--------------------- Main/fg_serial.hxx | 41 ++++++--- Main/options.cxx | 49 ++++------- Main/options.hxx | 32 ++++--- 4 files changed, 171 insertions(+), 155 deletions(-) diff --git a/Main/fg_serial.cxx b/Main/fg_serial.cxx index a0437a975..800ec60d9 100644 --- a/Main/fg_serial.cxx +++ b/Main/fg_serial.cxx @@ -23,7 +23,14 @@ #include // atoi() + #include +#include +#include "Include/fg_stl_config.h" + +#ifdef NEEDNAMESPACESTD +using namespace std; +#endif #include #include @@ -36,27 +43,34 @@ #include "fg_serial.hxx" -// support up to four serial channels. Each channel can be assigned -// to an arbitrary port. Bi-directional communication is supported by -// the underlying layer. +// support an arbitrary number of serial channels. Each channel can +// be assigned to an arbitrary port. Bi-directional communication is +// supported by the underlying layer, but probably will never be +// needed by FGFS? + +typedef vector < fgIOCHANNEL > io_container; +typedef io_container::iterator io_iterator; +typedef io_container::const_iterator const_io_iterator; // define the four channels -fgSERIAL port_a; -fgSERIAL port_b; -fgSERIAL port_c; -fgSERIAL port_d; +io_container port_list; + -// the type of each channel -fgSerialPortKind port_a_kind = FG_SERIAL_DISABLED; -fgSerialPortKind port_b_kind = FG_SERIAL_DISABLED; -fgSerialPortKind port_c_kind = FG_SERIAL_DISABLED; -fgSerialPortKind port_d_kind = FG_SERIAL_DISABLED; +fgIOCHANNEL::fgIOCHANNEL() : + kind( FG_SERIAL_DISABLED ) +{ +} + + +fgIOCHANNEL::~fgIOCHANNEL() { +} // configure a port based on the config string -static bool config_port(fgSERIAL& s, fgSerialPortKind& kind, - const string& config) +static fgIOCHANNEL config_port( const string& config ) { + fgIOCHANNEL p; + string::size_type begin, end; string device; @@ -64,108 +78,106 @@ static bool config_port(fgSERIAL& s, fgSerialPortKind& kind, string baud; string direction; - begin = 0;; + begin = 0; + + FG_LOG( FG_SERIAL, FG_INFO, "Configuring serial port: " << config ); // device name end = config.find(",", begin); if ( end == string::npos ) { - return false; + return p; } device = config.substr(begin, end - begin); begin = end + 1; - cout << " device = " << device << endl; + FG_LOG( FG_SERIAL, FG_INFO, " device = " << device ); // format end = config.find(",", begin); if ( end == string::npos ) { - return false; + return p; } format = config.substr(begin, end - begin); begin = end + 1; - cout << " format = " << format << endl; + FG_LOG( FG_SERIAL, FG_INFO, " format = " << format ); // baud end = config.find(",", begin); if ( end == string::npos ) { - return false; + return p; } baud = config.substr(begin, end - begin); begin = end + 1; - cout << " baud = " << baud << endl; + FG_LOG( FG_SERIAL, FG_INFO, " baud = " << baud ); // direction direction = config.substr(begin); - cout << " direction = " << direction << endl; + FG_LOG( FG_SERIAL, FG_INFO, " direction = " << direction ); - if ( s.is_enabled() ) { + if ( p.port.is_enabled() ) { FG_LOG( FG_SERIAL, FG_ALERT, "This shouldn't happen, but the port " << "is already in use, ignoring" ); - return false; + return p; } - if ( ! s.open_port( device ) ) { + if ( ! p.port.open_port( device ) ) { FG_LOG( FG_SERIAL, FG_ALERT, "Error opening device: " << device ); + return p; } - if ( ! s.set_baud( atoi( baud.c_str() ) ) ) { + if ( ! p.port.set_baud( atoi( baud.c_str() ) ) ) { FG_LOG( FG_SERIAL, FG_ALERT, "Error setting baud: " << baud ); + return p; } if ( format == "nmea" ) { if ( direction == "out" ) { - kind = FG_SERIAL_NMEA_OUT; + p.kind = fgIOCHANNEL::FG_SERIAL_NMEA_OUT; } else if ( direction == "in" ) { - kind = FG_SERIAL_NMEA_IN; + p.kind = fgIOCHANNEL::FG_SERIAL_NMEA_IN; } else { FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" ); - return false; } } else if ( format == "garman" ) { if ( direction == "out" ) { - kind = FG_SERIAL_GARMAN_OUT; + p.kind = fgIOCHANNEL::FG_SERIAL_GARMAN_OUT; } else if ( direction == "in" ) { - kind = FG_SERIAL_GARMAN_IN; + p.kind = fgIOCHANNEL::FG_SERIAL_GARMAN_IN; } else { FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" ); - return false; } } else if ( format == "fgfs" ) { if ( direction == "out" ) { - kind = FG_SERIAL_FGFS_OUT; + p.kind = fgIOCHANNEL::FG_SERIAL_FGFS_OUT; } else if ( direction == "in" ) { - kind = FG_SERIAL_FGFS_IN; + p.kind = fgIOCHANNEL::FG_SERIAL_FGFS_IN; } else { FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" ); - return false; } } else { FG_LOG( FG_SERIAL, FG_ALERT, "Unknown format" ); - return false; } - return true; + return p; } -// initialize serial ports based on command line options (if any) +// step through the port config streams (from fgOPTIONS) and setup +// serial port channels for each void fgSerialInit() { - if ( current_options.get_port_a_config() != "" ) { - config_port(port_a, port_a_kind, current_options.get_port_a_config() ); - } + fgIOCHANNEL port; + str_container port_options_list = current_options.get_port_options_list(); - if ( current_options.get_port_b_config() != "" ) { - config_port(port_b, port_b_kind, current_options.get_port_b_config() ); - } - - if ( current_options.get_port_c_config() != "" ) { - config_port(port_c, port_c_kind, current_options.get_port_c_config() ); - } + const_str_iterator current = port_options_list.begin(); + const_str_iterator last = port_options_list.end(); - if ( current_options.get_port_d_config() != "" ) { - config_port(port_d, port_d_kind, current_options.get_port_d_config() ); + for ( ; current != last; ++current ) { + port = config_port( *current ); + if ( port.kind != fgIOCHANNEL::FG_SERIAL_DISABLED ) { + port_list.push_back( port ); + } } } @@ -189,7 +201,7 @@ char calc_nmea_cksum(char *sentence) { } -static void send_nmea_out( fgSERIAL& s ) { +static void send_nmea_out( fgIOCHANNEL& p ) { char rmc[256], gga[256]; char rmc_sum[10], gga_sum[10]; char dir; @@ -198,6 +210,12 @@ static void send_nmea_out( fgSERIAL& s ) { fgFLIGHT *f; fgTIME *t; + // run once per second + if ( p.last_time == cur_time_params.cur_time ) { + return; + } + p.last_time = cur_time_params.cur_time; + f = current_aircraft.flight; t = &cur_time_params; @@ -266,7 +284,7 @@ static void send_nmea_out( fgSERIAL& s ) { rmc_sentence += "*"; rmc_sentence += rmc_sum; rmc_sentence += "\r\n"; - s.write_port(rmc_sentence); + p.port.write_port(rmc_sentence); } else { // gga on odd seconds string gga_sentence = "$"; @@ -274,14 +292,14 @@ static void send_nmea_out( fgSERIAL& s ) { gga_sentence += "*"; gga_sentence += gga_sum; gga_sentence += "\n"; - // s.write_port(gga_sentence); + // p.port.write_port(gga_sentence); } } -static void read_nmea_in( fgSERIAL& s ) { +static void read_nmea_in( fgIOCHANNEL& p ) { } -static void send_garman_out( fgSERIAL& s ) { +static void send_garman_out( fgIOCHANNEL& p ) { char rmc[256], rmz[256]; char dir; int deg; @@ -289,6 +307,12 @@ static void send_garman_out( fgSERIAL& s ) { fgFLIGHT *f; fgTIME *t; + // run once per second + if ( p.last_time == cur_time_params.cur_time ) { + return; + } + p.last_time = cur_time_params.cur_time; + f = current_aircraft.flight; t = &cur_time_params; @@ -352,69 +376,61 @@ static void send_garman_out( fgSERIAL& s ) { // one full frame every 2 seconds according to the standard if ( cur_time_params.cur_time % 2 == 0 ) { // rmc on even seconds - s.write_port(rmc); + p.port.write_port(rmc); } else { - // gga on odd seconds - s.write_port(rmz); + // rmz on odd seconds + p.port.write_port(rmz); } } -static void read_garman_in( fgSERIAL& s ) { +static void read_garman_in( fgIOCHANNEL& p ) { } -static void send_fgfs_out( fgSERIAL& s ) { +static void send_fgfs_out( fgIOCHANNEL& p ) { } -static void read_fgfs_in( fgSERIAL& s ) { +static void read_fgfs_in( fgIOCHANNEL& p ) { } // one more level of indirection ... -static void process_port( fgSERIAL& s, const fgSerialPortKind kind ) { - static long last_time; - if ( kind == FG_SERIAL_NMEA_OUT ) { - if (cur_time_params.cur_time > last_time ) { - send_nmea_out(s); - } - last_time = cur_time_params.cur_time; - } else if ( kind == FG_SERIAL_NMEA_IN ) { - read_nmea_in(s); - } else if ( kind == FG_SERIAL_GARMAN_OUT ) { - if (cur_time_params.cur_time > last_time ) { - send_garman_out(s); - } - last_time = cur_time_params.cur_time; - } else if ( kind == FG_SERIAL_GARMAN_IN ) { - read_garman_in(s); - } else if ( kind == FG_SERIAL_FGFS_OUT ) { - send_fgfs_out(s); - } else if ( kind == FG_SERIAL_FGFS_IN ) { - read_fgfs_in(s); +static void process_port( fgIOCHANNEL& p ) { + if ( p.kind == fgIOCHANNEL::FG_SERIAL_NMEA_OUT ) { + send_nmea_out(p); + } else if ( p.kind == fgIOCHANNEL::FG_SERIAL_NMEA_IN ) { + read_nmea_in(p); + } else if ( p.kind == fgIOCHANNEL::FG_SERIAL_GARMAN_OUT ) { + send_garman_out(p); + } else if ( p.kind == fgIOCHANNEL::FG_SERIAL_GARMAN_IN ) { + read_garman_in(p); + } else if ( p.kind == fgIOCHANNEL::FG_SERIAL_FGFS_OUT ) { + send_fgfs_out(p); + } else if ( p.kind == fgIOCHANNEL::FG_SERIAL_FGFS_IN ) { + read_fgfs_in(p); } } // process any serial port work void fgSerialProcess() { - if ( port_a_kind != FG_SERIAL_DISABLED ) { - process_port(port_a, port_a_kind); - } - - if ( port_b_kind != FG_SERIAL_DISABLED ) { - process_port(port_b, port_b_kind); - } - - if ( port_c_kind != FG_SERIAL_DISABLED ) { - process_port(port_c, port_c_kind); - } + fgIOCHANNEL port; + + const_io_iterator current = port_list.begin(); + const_io_iterator last = port_list.end(); - if ( port_d_kind != FG_SERIAL_DISABLED ) { - process_port(port_d, port_d_kind); + for ( ; current != last; ++current ) { + port = *current; + if ( port.kind != fgIOCHANNEL::FG_SERIAL_DISABLED ) { + process_port ( port ); + } } } // $Log$ +// Revision 1.4 1998/11/25 01:33:58 curt +// Support for an arbitrary number of serial ports. +// // Revision 1.3 1998/11/23 20:51:51 curt // Tweaking serial stuff. // diff --git a/Main/fg_serial.hxx b/Main/fg_serial.hxx index 127dcae61..80fe1b904 100644 --- a/Main/fg_serial.hxx +++ b/Main/fg_serial.hxx @@ -34,15 +34,27 @@ #include -// Types of serial port protocols -enum fgSerialPortKind { - FG_SERIAL_DISABLED = 0, - FG_SERIAL_NMEA_OUT = 1, - FG_SERIAL_NMEA_IN = 2, - FG_SERIAL_GARMAN_OUT = 3, - FG_SERIAL_GARMAN_IN = 4, - FG_SERIAL_FGFS_OUT = 5, - FG_SERIAL_FGFS_IN = 6 +class fgIOCHANNEL { + +public: + + // Types of serial port protocols + enum fgPortKind { + FG_SERIAL_DISABLED = 0, + FG_SERIAL_NMEA_OUT = 1, + FG_SERIAL_NMEA_IN = 2, + FG_SERIAL_GARMAN_OUT = 3, + FG_SERIAL_GARMAN_IN = 4, + FG_SERIAL_FGFS_OUT = 5, + FG_SERIAL_FGFS_IN = 6 + }; + + fgPortKind kind; + fgSERIAL port; + long last_time; + + fgIOCHANNEL(); + ~fgIOCHANNEL(); }; @@ -51,10 +63,10 @@ enum fgSerialPortKind { // the underlying layer. // define the four channels -extern fgSERIAL port_a; -extern fgSERIAL port_b; -extern fgSERIAL port_c; -extern fgSERIAL port_d; +// extern fgIOCHANNEL port_a; +// extern fgIOCHANNEL port_b; +// extern fgIOCHANNEL port_c; +// extern fgIOCHANNEL port_d; // initialize serial ports based on command line options (if any) @@ -69,6 +81,9 @@ void fgSerialProcess(); // $Log$ +// Revision 1.3 1998/11/25 01:33:59 curt +// Support for an arbitrary number of serial ports. +// // Revision 1.2 1998/11/19 13:53:27 curt // Added a "Garman" mode. // diff --git a/Main/options.cxx b/Main/options.cxx index fe589792a..256787e7e 100644 --- a/Main/options.cxx +++ b/Main/options.cxx @@ -150,18 +150,7 @@ fgOPTIONS::fgOPTIONS() : tris_or_culled(0), // Time options - time_offset(0), - - // Serial port options - // port_a(FG_SERIAL_DISABLED), - // port_b(FG_SERIAL_DISABLED), - // port_c(FG_SERIAL_DISABLED), - // port_d(FG_SERIAL_DISABLED), - - port_a_config(""), - port_b_config(""), - port_c_config(""), - port_d_config("") + time_offset(0) { // set initial values/defaults @@ -184,6 +173,10 @@ fgOPTIONS::fgOPTIONS() : } airport_id = ""; // default airport id + + // initialize port config string list + port_options_list.erase ( port_options_list.begin(), + port_options_list.end() ); } @@ -344,25 +337,23 @@ fgOPTIONS::parse_fov( const string& arg ) { } -// Parse serial port option --serial=a,/dev/ttyS1,nmea,4800,out +// Parse serial port option --serial=/dev/ttyS1,nmea,4800,out // -// Format is "--serial=port_id,device,format,baud,direction" where +// Format is "--serial=device,format,baud,direction" where // -// port_id = {a, b, c, d} // device = OS device name to be open()'ed // format = {nmea, fgfs} // baud = {300, 1200, 2400, ..., 230400} // direction = {in, out, bi} -// + bool fgOPTIONS::parse_serial( const string& serial_str ) { string::size_type pos; - string port; - string config; // cout << "Serial string = " << serial_str << endl; - // port + // a flailing attempt to see if the port config string has a + // chance at being valid pos = serial_str.find(","); if ( pos == string::npos ) { FG_LOG( FG_GENERAL, FG_ALERT, @@ -370,22 +361,7 @@ fgOPTIONS::parse_serial( const string& serial_str ) { return false; } - port = serial_str.substr(0, pos); - config = serial_str.substr(++pos); - - if ( port == "a" ) { - port_a_config = config; - } else if ( port == "b" ) { - port_b_config = config; - } else if ( port == "c" ) { - port_c_config = config; - } else if ( port == "d" ) { - port_d_config = config; - } else { - FG_LOG( FG_GENERAL, FG_ALERT, "Valid ports are a - d, config for port " - << port << " ignored" ); - return false; - } + port_options_list.push_back( serial_str ); return true; } @@ -642,6 +618,9 @@ fgOPTIONS::~fgOPTIONS( void ) { // $Log$ +// Revision 1.32 1998/11/25 01:34:00 curt +// Support for an arbitrary number of serial ports. +// // Revision 1.31 1998/11/23 21:49:04 curt // Borland portability tweaks. // diff --git a/Main/options.hxx b/Main/options.hxx index 491f3a7b6..994068b25 100644 --- a/Main/options.hxx +++ b/Main/options.hxx @@ -45,9 +45,21 @@ #include FG_USING_STD(string); +#include +#include "Include/fg_stl_config.h" + +#ifdef NEEDNAMESPACESTD +using namespace std; +#endif + #include "fg_serial.hxx" +typedef vector < string > str_container; +typedef str_container::iterator str_iterator; +typedef str_container::const_iterator const_str_iterator; + + class fgOPTIONS { public: @@ -139,10 +151,7 @@ private: // fgSerialPortKind port_d_kind; // Port d kind // Serial port configuration strings - string port_a_config; - string port_b_config; - string port_c_config; - string port_d_config; + str_container port_options_list; public: @@ -197,15 +206,9 @@ public: inline int get_time_offset() const { return time_offset; } - // inline fgSerialPortKind get_port_a_kind() const { return port_a_kind; } - // inline fgSerialPortKind get_port_b_kind() const { return port_b_kind; } - // inline fgSerialPortKind get_port_c_kind() const { return port_c_kind; } - // inline fgSerialPortKind get_port_d_kind() const { return port_d_kind; } - - inline string get_port_a_config() const { return port_a_config; } - inline string get_port_b_config() const { return port_b_config; } - inline string get_port_c_config() const { return port_c_config; } - inline string get_port_d_config() const { return port_d_config; } + inline str_container get_port_options_list() const { + return port_options_list; + } // Update functions inline void set_hud_status( bool status ) { hud_status = status; } @@ -244,6 +247,9 @@ extern fgOPTIONS current_options; // $Log$ +// Revision 1.24 1998/11/25 01:34:01 curt +// Support for an arbitrary number of serial ports. +// // Revision 1.23 1998/11/23 21:49:05 curt // Borland portability tweaks. // -- 2.39.5