]> git.mxchange.org Git - flightgear.git/commitdiff
Support for an arbitrary number of serial ports.
authorcurt <curt>
Wed, 25 Nov 1998 01:33:58 +0000 (01:33 +0000)
committercurt <curt>
Wed, 25 Nov 1998 01:33:58 +0000 (01:33 +0000)
Main/fg_serial.cxx
Main/fg_serial.hxx
Main/options.cxx
Main/options.hxx

index a0437a975f86bd1a3cafc87732b4b33ae02978f8..800ec60d9d5d7849595b7c21cb64010b9ed11b6a 100644 (file)
 
 
 #include <stdlib.h>   // atoi()
+
 #include <string>
+#include <vector>                                                               
+#include "Include/fg_stl_config.h"                                              
+
+#ifdef NEEDNAMESPACESTD                                                         
+using namespace std;                                                            
+#endif                                                                          
 
 #include <Aircraft/aircraft.hxx>
 #include <Debug/logstream.hxx>
 #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.
 //
index 127dcae61c5c758ea70fc1413efc4d7e8fedb83b..80fe1b9043bdc7a001014638d5c005e1688061df 100644 (file)
 #include <Serial/serial.hxx>
 
 
-// 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.
 //
index fe589792afcca1a3b83d672b1b61aa4f8330a553..256787e7e981a2c4e06bb9e0b6089f9f06100491 100644 (file)
@@ -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.
 //
index 491f3a7b6f5e003f5385487553ba4e4ae7c824db..994068b250bdcf4ea56a4fefccf80ba7016bb020 100644 (file)
 #include <Include/compiler.h>
 FG_USING_STD(string);
 
+#include <vector>                                                               
+#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.
 //