]> git.mxchange.org Git - simgear.git/blobdiff - simgear/serial/serial.cxx
Frederic BOUVIER:
[simgear.git] / simgear / serial / serial.cxx
index a46570d240b6a89d6f202f7733f5ffc05cd63d85..3c24f87789559a4791fe198325da5119161b1a2b 100644 (file)
 // $Id$
 
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
 #include <simgear/compiler.h>
 
+#include STL_IOSTREAM
+
 #ifdef SG_HAVE_STD_INCLUDE
 #  include <cerrno>
 #else
 #  include <errno.h>
 #endif
 
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
-  // maybe include something???
-#else
+#if !defined( WIN32 ) || defined( __CYGWIN__) || defined( __CYGWIN32__ )
 #  include <termios.h>
 #  include <sys/types.h>
 #  include <sys/stat.h>
 
 #include "serial.hxx"
 
-
-FGSerialPort::FGSerialPort()
+SGSerialPort::SGSerialPort()
     : dev_open(false)
 {
     // empty
 }
 
-FGSerialPort::FGSerialPort(const string& device, int baud) {
+SGSerialPort::SGSerialPort(const string& device, int baud) {
     open_port(device);
     
     if ( dev_open ) {
@@ -63,13 +58,13 @@ FGSerialPort::FGSerialPort(const string& device, int baud) {
     }
 }
 
-FGSerialPort::~FGSerialPort() {
+SGSerialPort::~SGSerialPort() {
     // closing the port here screws us up because if we would even so
-    // much as make a copy of an FGSerialPort object and then delete it,
+    // much as make a copy of an SGSerialPort object and then delete it,
     // the file descriptor gets closed.  Doh!!!
 }
 
-bool FGSerialPort::open_port(const string& device) {
+bool SGSerialPort::open_port(const string& device) {
 
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
 
@@ -78,7 +73,7 @@ bool FGSerialPort::open_port(const string& device) {
         0, // dwShareMode
         NULL, // lpSecurityAttributes
         OPEN_EXISTING,
-        FILE_FLAG_OVERLAPPED,
+        0,
         NULL );
     if ( fd == INVALID_HANDLE_VALUE )
     {
@@ -94,7 +89,7 @@ bool FGSerialPort::open_port(const string& device) {
             0,
             NULL );
 
-        FG_LOG( FG_IO, FG_ALERT, "Error opening serial device \"" 
+        SG_LOG( SG_IO, SG_ALERT, "Error opening serial device \"" 
             << device << "\" " << (const char*) lpMsgBuf );
         LocalFree( lpMsgBuf );
         return false;
@@ -108,10 +103,10 @@ bool FGSerialPort::open_port(const string& device) {
     struct termios config;
 
     fd = open(device.c_str(), O_RDWR | O_NONBLOCK);
-    cout << "Serial fd created = " << fd << endl;
+    SG_LOG( SG_EVENT, SG_DEBUG, "Serial fd created = " << fd);
 
     if ( fd  == -1 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Cannot open " << device
+       SG_LOG( SG_IO, SG_ALERT, "Cannot open " << device
                << " for serial I/O" );
        return false;
     } else {
@@ -120,7 +115,7 @@ bool FGSerialPort::open_port(const string& device) {
 
     // set required port parameters 
     if ( tcgetattr( fd, &config ) != 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Unable to poll port settings" );
+       SG_LOG( SG_IO, SG_ALERT, "Unable to poll port settings" );
        return false;
     }
 
@@ -142,7 +137,7 @@ bool FGSerialPort::open_port(const string& device) {
     // cout << "config.c_iflag = " << config.c_iflag << endl;
 
     if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Unable to update port settings" );
+       SG_LOG( SG_IO, SG_ALERT, "Unable to update port settings" );
        return false;
     }
 
@@ -151,7 +146,7 @@ bool FGSerialPort::open_port(const string& device) {
 }
 
 
-bool FGSerialPort::close_port() {
+bool SGSerialPort::close_port() {
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
     CloseHandle( fd );
 #else
@@ -164,10 +159,55 @@ bool FGSerialPort::close_port() {
 }
 
 
-bool FGSerialPort::set_baud(int baud) {
+bool SGSerialPort::set_baud(int baud) {
 
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
 
+    DCB dcb;
+    if ( GetCommState( fd, &dcb ) ) {
+        dcb.BaudRate = baud;
+        dcb.fOutxCtsFlow = FALSE;
+        dcb.fOutxDsrFlow = FALSE;
+        dcb.fOutX = TRUE;
+        dcb.fInX = TRUE;
+
+        if ( !SetCommState( fd, &dcb ) ) {
+            LPVOID lpMsgBuf;
+            FormatMessage(
+                FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+                FORMAT_MESSAGE_FROM_SYSTEM | 
+                FORMAT_MESSAGE_IGNORE_INSERTS,
+                NULL,
+                GetLastError(),
+                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                (LPTSTR) &lpMsgBuf,
+                0,
+                NULL );
+
+            SG_LOG( SG_IO, SG_ALERT, "Unable to update port settings: " 
+                << (const char*) lpMsgBuf );
+            LocalFree( lpMsgBuf );
+           return false;
+        }
+    } else {
+        LPVOID lpMsgBuf;
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+            FORMAT_MESSAGE_FROM_SYSTEM | 
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL );
+
+        SG_LOG( SG_IO, SG_ALERT, "Unable to poll port settings: " 
+             << (const char*) lpMsgBuf );
+        LocalFree( lpMsgBuf );
+       return false;
+    }
+
     return true;
 
 #else
@@ -176,7 +216,7 @@ bool FGSerialPort::set_baud(int baud) {
     speed_t speed = B9600;
 
     if ( tcgetattr( fd, &config ) != 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Unable to poll port settings" );
+       SG_LOG( SG_IO, SG_ALERT, "Unable to poll port settings" );
        return false;
     }
 
@@ -203,22 +243,22 @@ bool FGSerialPort::set_baud(int baud) {
        speed = B230400;
 #endif
     } else {
-       FG_LOG( FG_IO, FG_ALERT, "Unsupported baud rate " << baud );
+       SG_LOG( SG_IO, SG_ALERT, "Unsupported baud rate " << baud );
        return false;
     }
 
     if ( cfsetispeed( &config, speed ) != 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Problem setting input baud rate" );
+       SG_LOG( SG_IO, SG_ALERT, "Problem setting input baud rate" );
        return false;
     }
 
     if ( cfsetospeed( &config, speed ) != 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Problem setting output baud rate" );
+       SG_LOG( SG_IO, SG_ALERT, "Problem setting output baud rate" );
        return false;
     }
 
     if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Unable to update port settings" );
+       SG_LOG( SG_IO, SG_ALERT, "Unable to update port settings" );
        return false;
     }
 
@@ -228,27 +268,47 @@ bool FGSerialPort::set_baud(int baud) {
 
 }
 
-string FGSerialPort::read_port() {
+string SGSerialPort::read_port() {
+
+    const int max_count = 1024;
+    char buffer[max_count+1];
+    string result;
 
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
 
-    string result = "";
+    DWORD count;
+    if ( ReadFile( fd, buffer, max_count, &count, 0 ) ) {
+       buffer[count] = '\0';
+        result = buffer;
+    } else {
+        LPVOID lpMsgBuf;
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+            FORMAT_MESSAGE_FROM_SYSTEM | 
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL );
+
+        SG_LOG( SG_IO, SG_ALERT, "Serial I/O read error: " 
+             << (const char*) lpMsgBuf );
+        LocalFree( lpMsgBuf );
+    }
+
     return result;
 
 #else
 
-    const int max_count = 1024;
-    char buffer[max_count+1];
-    int count;
-    string result;
-
-    count = read(fd, buffer, max_count);
+    int count = read(fd, buffer, max_count);
     // cout << "read " << count << " bytes" << endl;
 
     if ( count < 0 ) {
        // error condition
        if ( errno != EAGAIN ) {
-           FG_LOG( FG_IO, FG_ALERT, 
+           SG_LOG( SG_IO, SG_ALERT, 
                    "Serial I/O on read, error number = " << errno );
        }
 
@@ -264,12 +324,35 @@ string FGSerialPort::read_port() {
 
 }
 
-int FGSerialPort::read_port(char *buf, int len) {
+int SGSerialPort::read_port(char *buf, int len) {
 
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
 
-    buf[0] = '\0';
-    return 0;
+    DWORD count;
+    if ( ReadFile( fd, buf, len, &count, 0 ) ) {
+       buf[count] = '\0';
+
+        return count;
+    } else {
+        LPVOID lpMsgBuf;
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+            FORMAT_MESSAGE_FROM_SYSTEM | 
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL );
+
+        SG_LOG( SG_IO, SG_ALERT, "Serial I/O read error: " 
+             << (const char*) lpMsgBuf );
+        LocalFree( lpMsgBuf );
+
+       buf[0] = '\0';
+       return 0;
+    }
 
 #else
 
@@ -281,7 +364,7 @@ int FGSerialPort::read_port(char *buf, int len) {
     if ( count < 0 ) {
        // error condition
        if ( errno != EAGAIN ) {
-           FG_LOG( FG_IO, FG_ALERT, 
+           SG_LOG( SG_IO, SG_ALERT, 
                    "Serial I/O on read, error number = " << errno );
        }
 
@@ -298,20 +381,19 @@ int FGSerialPort::read_port(char *buf, int len) {
 }
 
 
-int FGSerialPort::write_port(const string& value) {
+int SGSerialPort::write_port(const string& value) {
 
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
 
-    LPCVOID lpBuffer = value.c_str();
+    LPCVOID lpBuffer = value.data();
     DWORD nNumberOfBytesToWrite = value.length();
     DWORD lpNumberOfBytesWritten;
-    OVERLAPPED lpOverlapped;
 
     if ( WriteFile( fd,
         lpBuffer,
         nNumberOfBytesToWrite,
         &lpNumberOfBytesWritten,
-        &lpOverlapped ) == 0 )
+        0 ) == 0 )
     {
         LPVOID lpMsgBuf;
         FormatMessage(
@@ -325,7 +407,7 @@ int FGSerialPort::write_port(const string& value) {
             0,
             NULL );
 
-        FG_LOG( FG_IO, FG_ALERT, "Serial I/O write error: " 
+        SG_LOG( SG_IO, SG_ALERT, "Serial I/O write error: " 
              << (const char*) lpMsgBuf );
         LocalFree( lpMsgBuf );
         return int(lpNumberOfBytesWritten);
@@ -339,7 +421,7 @@ int FGSerialPort::write_port(const string& value) {
     int count;
 
     if ( error ) {
-        FG_LOG( FG_IO, FG_ALERT, "attempting serial write error recovery" );
+        SG_LOG( SG_IO, SG_ALERT, "attempting serial write error recovery" );
        // attempt some sort of error recovery
        count = write(fd, "\n", 1);
        if ( count == 1 ) {
@@ -362,7 +444,7 @@ int FGSerialPort::write_port(const string& value) {
            error = false;
        } else {
            error = true;
-           FG_LOG( FG_IO, FG_ALERT,
+           SG_LOG( SG_IO, SG_ALERT,
                    "Serial I/O on write, error number = " << errno );
        }
     }
@@ -374,19 +456,18 @@ int FGSerialPort::write_port(const string& value) {
 }
 
 
-int FGSerialPort::write_port(const char* buf, int len) {
+int SGSerialPort::write_port(const char* buf, int len) {
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
 
     LPCVOID lpBuffer = buf;
     DWORD nNumberOfBytesToWrite = len;
     DWORD lpNumberOfBytesWritten;
-    OVERLAPPED lpOverlapped;
 
     if ( WriteFile( fd,
         lpBuffer,
         nNumberOfBytesToWrite,
         &lpNumberOfBytesWritten,
-        &lpOverlapped ) == 0 )
+        0 ) == 0 )
     {
         LPVOID lpMsgBuf;
         FormatMessage(
@@ -400,7 +481,7 @@ int FGSerialPort::write_port(const char* buf, int len) {
             0,
             NULL );
 
-        FG_LOG( FG_IO, FG_ALERT, "Serial I/O write error: " 
+        SG_LOG( SG_IO, SG_ALERT, "Serial I/O write error: " 
              << (const char*) lpMsgBuf );
         LocalFree( lpMsgBuf );
         return int(lpNumberOfBytesWritten);
@@ -435,7 +516,7 @@ int FGSerialPort::write_port(const char* buf, int len) {
            // ok ... in our context we don't really care if we can't
            // write a string, we'll just get it the next time around
        } else {
-           FG_LOG( FG_IO, FG_ALERT,
+           SG_LOG( SG_IO, SG_ALERT,
                    "Serial I/O on write, error number = " << errno );
        }
     }