From d7facce4de9a52419ab8998a422be425db9d76c9 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Tue, 17 May 2016 07:44:08 +0200 Subject: [PATCH] Major update: - Convert PortCore functions into Class Bug fixes: - Correctly handle socket close event (return false on read) - Only write to port/socket if valid file handle --- PortCore.cpp | 163 ++++++++++++++++++++++++++++--------------------- PortCore.h | 37 ++++++++--- SocketCore.cpp | 75 ++++++++++++----------- 3 files changed, 163 insertions(+), 112 deletions(-) diff --git a/PortCore.cpp b/PortCore.cpp index e266610..f2892b8 100644 --- a/PortCore.cpp +++ b/PortCore.cpp @@ -6,8 +6,8 @@ */ // redA Libraries -#include "TimingCore.h" #include "PortCore.h" +#include "TimingCore.h" // Standard C/C++ Libraries #include @@ -21,68 +21,93 @@ //--------------------------------------------------------------------------- -// Port Def -int PortHandle = -1; -char * PortName = NULL; - -// PortIn buffer -char PortInBuffer[500] = ""; -int PortInBufLen = 500; -int PortInLen = 0; -int PortBytesRead = 0; - -// PortIn Timer -timeval PortInStart = { 0, 0 }; -long PortInTimeout = 100; // millisecs - -//--------------------------------------------------------------------------- - -int OpenPort( const char * pPortName ) +CPortCore::CPortCore( const char * PortName, const int PortInBufLen ) : InBufLen( PortInBufLen ) { + // Port File Handle + Handle = -1; + // Copy Port name - PortName = (char*)malloc( strlen(pPortName)+ 1); - strcpy( PortName, pPortName ); - - // Check if port exits - if (access( PortName, F_OK ) != 0) - { - printf( "Port: %s -> Could not find port\n", PortName ); - return -1; + if (PortName) { + Name = (char*)malloc( strlen( PortName)+ 1); + strcpy( Name, PortName ); + } + else { + Name = NULL; } - // Open Port - PortHandle = open( PortName, O_RDWR ); - if (PortHandle == -1) - { - printf( "Port: %s -> Could not open port\n", PortName ); - return -1; - } + // In buffer + InBuffer = (char *)malloc( InBufLen ); + InLen = 0; + BytesRead = 0; - // Confirm open - printf( "Port: %s -> Port opened\n", PortName ); - return PortHandle; + // In buffer Timer + InStart.tv_sec = 0; + InStart.tv_usec = 0; + InTimeout = 100; // millisecs } //--------------------------------------------------------------------------- -bool ClosePort() +CPortCore::~CPortCore() +{ + // Destroy pointers + if (Name) { + free( Name ); + } +} +//--------------------------------------------------------------------------- + +bool CPortCore::Open() +{ + // Check if valid port name + if (!Name) { + return false; + } + + // Check if port exits + if (access( Name, F_OK ) != 0) + { + printf( "Port: %s -> Could not find port\n", Name ); + return false; + } + + // Open Port + Handle = open( Name, O_RDWR ); + if (Handle == -1) + { + printf( "Port: %s -> Could not open port\n", Name ); + return false; + } + + // Confirm open + printf( "Port: %s -> Port opened\n", Name ); + return true; +} +//--------------------------------------------------------------------------- + +bool CPortCore::Close() { int result; + // Check if valid port + if (Handle == -1) { + return true; + } + // Close port - result = close( PortHandle ); + result = close( Handle ); if (result) { - printf( "Port: %s -> Port not closed properly\n", PortName ); + printf( "Port: %s -> Port not closed properly\n", Name ); return false; } // Port closed - printf( "Port: %s -> Port closed\n", PortName ); + printf( "Port: %s -> Port closed\n", Name ); return true; } //--------------------------------------------------------------------------- // Set serial port configuration parameters -bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ) +bool CPortCore::Config( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ) { struct termios newtio; int flags = 0; @@ -90,14 +115,14 @@ bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, s int mcs = 0; // Flush Data from port - tcflush( PortHandle, TCIFLUSH ); + tcflush( Handle, TCIFLUSH ); // Set Open flags - flags = fcntl( PortHandle, F_GETFL, 0 ); - fcntl( PortHandle, F_SETFL, flags & ~O_NDELAY ); + flags = fcntl( Handle, F_GETFL, 0 ); + fcntl( Handle, F_SETFL, flags & ~O_NDELAY ); // Read options - if (tcgetattr( PortHandle, &newtio ) != 0) + if (tcgetattr( Handle, &newtio ) != 0) return false; // Process the baud rate @@ -189,16 +214,16 @@ bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, s // Set Options (first time) //tcflush( Handle, TCIFLUSH); - if (tcsetattr( PortHandle, TCSANOW, &newtio)!=0) + if (tcsetattr( Handle, TCSANOW, &newtio)!=0) return false; // Set Terminal options - ioctl( PortHandle, TIOCMGET, &mcs); + ioctl( Handle, TIOCMGET, &mcs); mcs |= TIOCM_RTS; - ioctl( PortHandle, TIOCMSET, &mcs); + ioctl( Handle, TIOCMSET, &mcs); // Get Options (again) - if (tcgetattr( PortHandle, &newtio) != 0) + if (tcgetattr( Handle, &newtio) != 0) return false; // Process Hardware Flow Control @@ -208,62 +233,64 @@ bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, s newtio.c_cflag &= ~CRTSCTS; // Set Options (second time) - if (tcsetattr( PortHandle, TCSANOW, &newtio ) != 0) + if (tcsetattr( Handle, TCSANOW, &newtio ) != 0) { - printf( "Port: %s -> Could not configure port\n", PortName ); + printf( "Port: %s -> Could not configure port\n", Name ); return false; } // Port configured - printf( "Port: %s -> Port configured\n", PortName ); + printf( "Port: %s -> Port configured\n", Name ); return true; } //--------------------------------------------------------------------------- -bool ReadPort() +bool CPortCore::Read() { // Handle read event - PortBytesRead = read( PortHandle, &PortInBuffer[PortInLen], PortInBufLen-PortInLen ); - if (PortBytesRead > 0) + BytesRead = read( Handle, &InBuffer[InLen], InBufLen-InLen ); + if (BytesRead > 0) { // Process Reply - PortInLen += PortBytesRead; + InLen += BytesRead; // Reset timer - SetStartTime( &PortInStart ); + SetStartTime( &InStart ); } return true; } //--------------------------------------------------------------------------- -bool MaintainPort( int SocketHandle ) +bool CPortCore::Maintain( int SocketHandle ) { // Misc long Duration = 0; int BytesWritten = 0; int StartWrite = 0; - if (PortInLen > 0) + if (InLen > 0) { // Check duration since last PortIn - Duration = TimePassed( PortInStart ); - if (Duration > PortInTimeout) + Duration = TimePassed( InStart ); + if (Duration > InTimeout) { // Handle buffer as packet - PortInBuffer[ PortInLen ] = 0; - //ShowOutput( "Port", PortInBuffer, PortInLen, Duration ); + InBuffer[ InLen ] = 0; + //ShowOutput( "Port", InBuffer, PortInLen, Duration ); // Write output to Port BytesWritten = 0; StartWrite = 0; - while (StartWrite < PortInLen) { - BytesWritten = write( SocketHandle, &PortInBuffer[StartWrite], PortInLen ); - StartWrite += BytesWritten; + if (SocketHandle != -1) { + while (StartWrite < InLen) { + BytesWritten = write( SocketHandle, &InBuffer[StartWrite], InLen ); + StartWrite += BytesWritten; + } } // Reset buffer and timer - PortInLen = 0; - SetInterval( &PortInStart, 0 ); + InLen = 0; + SetInterval( &InStart, 0 ); } } return true; diff --git a/PortCore.h b/PortCore.h index e9705c8..b5fe0e9 100644 --- a/PortCore.h +++ b/PortCore.h @@ -12,7 +12,7 @@ /* none */ // Standard C/C++ Libraries -/* none */ +#include //--------------------------------------------------------------------------- @@ -28,13 +28,36 @@ #define SW_FLOWCTRL 2 //--------------------------------------------------------------------------- -// Port Functions -int OpenPort( const char * PortName ); -bool ClosePort(); -bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ); +// Port Core Class +class CPortCore +{ +private: + // Port Def + int Handle; + char * Name; -bool ReadPort(); -bool MaintainPort( int SocketHandle ); + // PortIn buffer + char * InBuffer; + int InBufLen; + int InLen; + int BytesRead; + + // PortIn Timer + timeval InStart; + long InTimeout; // millisecs + +public: + CPortCore( const char * PortName, const int PortInBufLen ); + ~CPortCore(); + + bool Open(); + bool Close(); + bool Config( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ); + int GetHandle() { return Handle; }; + + bool Read(); + bool Maintain( int SocketHandle ); +}; //--------------------------------------------------------------------------- #endif /* PORTCORE_H_ */ diff --git a/SocketCore.cpp b/SocketCore.cpp index 27d158c..b561836 100644 --- a/SocketCore.cpp +++ b/SocketCore.cpp @@ -297,44 +297,43 @@ bool ReadClientSocket() // Check if anything to read ioctl( ClientHandle, FIONREAD, &SockBytesWaiting ); - if (SockBytesWaiting) - { - // Handle Incoming Data - // Check if socket ready (non-block open not in progress) - if (ClientState == ssWaitingtoOpen) - { - printf( "Socket: %s -> Cannot read from socket in waiting\n", ServerName ); - SockBytesWaiting = 0; - } - else - { - // Read data into buffer - SockBytesRead = read( ClientHandle, &SockInBuffer[SockInLen], SockBytesWaiting ); // SockInBufLen-SockInLen - - // Check of errors - if (SockBytesRead == -1) - { - printf( "Socket: %s -> Cannot read from socket (%s)\n", ServerName, strerror(errno) ); - SockBytesRead = 0; - - // Check of non-blocking write - // bool Blocked = ((errno == EAGAIN)? true : false ); - } - else if (SockBytesRead > 0) - { - // Process Reply - SockInLen += SockBytesRead; - - // Reset timer - SetStartTime( &SockInStart ); - } - } - } - else // if (!SockBytesWaiting) + // Test for close event + if (!SockBytesWaiting) { // EOF from server (close connection) CloseTCPSocket( ctRemoteClient ); ClientHandle = -1; + return false; + } + // Check if socket ready (non-block open not in progress) + else if (ClientState == ssWaitingtoOpen) + { + printf( "Socket: %s -> Cannot read from socket in waiting\n", ServerName ); + SockBytesWaiting = 0; + } + // Handel incoming data + else + { + // Read data into buffer + SockBytesRead = read( ClientHandle, &SockInBuffer[SockInLen], SockBytesWaiting ); // SockInBufLen-SockInLen + + // Check of errors + if (SockBytesRead == -1) + { + printf( "Socket: %s -> Cannot read from socket (%s)\n", ServerName, strerror(errno) ); + SockBytesRead = 0; + + // Check of non-blocking write + // bool Blocked = ((errno == EAGAIN)? true : false ); + } + else if (SockBytesRead > 0) + { + // Process Reply + SockInLen += SockBytesRead; + + // Reset timer + SetStartTime( &SockInStart ); + } } return true; } @@ -360,9 +359,11 @@ bool MaintainSocket( int PortHandle ) // Write output to Port BytesWritten = 0; StartWrite = 0; - while (StartWrite < SockInLen) { - BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen ); - StartWrite += BytesWritten; + if (PortHandle != -1) { + while (StartWrite < SockInLen) { + BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen ); + StartWrite += BytesWritten; + } } // Reset buffer and timer