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
This commit is contained in:
Charl Wentzel
2016-05-17 07:44:08 +02:00
parent 264169e525
commit d7facce4de
3 changed files with 163 additions and 112 deletions

View File

@@ -6,8 +6,8 @@
*/ */
// redA Libraries // redA Libraries
#include "TimingCore.h"
#include "PortCore.h" #include "PortCore.h"
#include "TimingCore.h"
// Standard C/C++ Libraries // Standard C/C++ Libraries
#include <stdio.h> #include <stdio.h>
@@ -21,68 +21,93 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Port Def CPortCore::CPortCore( const char * PortName, const int PortInBufLen ) : InBufLen( PortInBufLen )
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 )
{ {
// Port File Handle
Handle = -1;
// Copy Port name // Copy Port name
PortName = (char*)malloc( strlen(pPortName)+ 1); if (PortName) {
strcpy( PortName, pPortName ); Name = (char*)malloc( strlen( PortName)+ 1);
strcpy( Name, PortName );
// Check if port exits }
if (access( PortName, F_OK ) != 0) else {
{ Name = NULL;
printf( "Port: %s -> Could not find port\n", PortName );
return -1;
} }
// Open Port // In buffer
PortHandle = open( PortName, O_RDWR ); InBuffer = (char *)malloc( InBufLen );
if (PortHandle == -1) InLen = 0;
{ BytesRead = 0;
printf( "Port: %s -> Could not open port\n", PortName );
return -1;
}
// Confirm open // In buffer Timer
printf( "Port: %s -> Port opened\n", PortName ); InStart.tv_sec = 0;
return PortHandle; 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; int result;
// Check if valid port
if (Handle == -1) {
return true;
}
// Close port // Close port
result = close( PortHandle ); result = close( Handle );
if (result) { if (result) {
printf( "Port: %s -> Port not closed properly\n", PortName ); printf( "Port: %s -> Port not closed properly\n", Name );
return false; return false;
} }
// Port closed // Port closed
printf( "Port: %s -> Port closed\n", PortName ); printf( "Port: %s -> Port closed\n", Name );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Set serial port configuration parameters // 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; struct termios newtio;
int flags = 0; int flags = 0;
@@ -90,14 +115,14 @@ bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, s
int mcs = 0; int mcs = 0;
// Flush Data from port // Flush Data from port
tcflush( PortHandle, TCIFLUSH ); tcflush( Handle, TCIFLUSH );
// Set Open flags // Set Open flags
flags = fcntl( PortHandle, F_GETFL, 0 ); flags = fcntl( Handle, F_GETFL, 0 );
fcntl( PortHandle, F_SETFL, flags & ~O_NDELAY ); fcntl( Handle, F_SETFL, flags & ~O_NDELAY );
// Read options // Read options
if (tcgetattr( PortHandle, &newtio ) != 0) if (tcgetattr( Handle, &newtio ) != 0)
return false; return false;
// Process the baud rate // Process the baud rate
@@ -189,16 +214,16 @@ bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, s
// Set Options (first time) // Set Options (first time)
//tcflush( Handle, TCIFLUSH); //tcflush( Handle, TCIFLUSH);
if (tcsetattr( PortHandle, TCSANOW, &newtio)!=0) if (tcsetattr( Handle, TCSANOW, &newtio)!=0)
return false; return false;
// Set Terminal options // Set Terminal options
ioctl( PortHandle, TIOCMGET, &mcs); ioctl( Handle, TIOCMGET, &mcs);
mcs |= TIOCM_RTS; mcs |= TIOCM_RTS;
ioctl( PortHandle, TIOCMSET, &mcs); ioctl( Handle, TIOCMSET, &mcs);
// Get Options (again) // Get Options (again)
if (tcgetattr( PortHandle, &newtio) != 0) if (tcgetattr( Handle, &newtio) != 0)
return false; return false;
// Process Hardware Flow Control // Process Hardware Flow Control
@@ -208,62 +233,64 @@ bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, s
newtio.c_cflag &= ~CRTSCTS; newtio.c_cflag &= ~CRTSCTS;
// Set Options (second time) // 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; return false;
} }
// Port configured // Port configured
printf( "Port: %s -> Port configured\n", PortName ); printf( "Port: %s -> Port configured\n", Name );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool ReadPort() bool CPortCore::Read()
{ {
// Handle read event // Handle read event
PortBytesRead = read( PortHandle, &PortInBuffer[PortInLen], PortInBufLen-PortInLen ); BytesRead = read( Handle, &InBuffer[InLen], InBufLen-InLen );
if (PortBytesRead > 0) if (BytesRead > 0)
{ {
// Process Reply // Process Reply
PortInLen += PortBytesRead; InLen += BytesRead;
// Reset timer // Reset timer
SetStartTime( &PortInStart ); SetStartTime( &InStart );
} }
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool MaintainPort( int SocketHandle ) bool CPortCore::Maintain( int SocketHandle )
{ {
// Misc // Misc
long Duration = 0; long Duration = 0;
int BytesWritten = 0; int BytesWritten = 0;
int StartWrite = 0; int StartWrite = 0;
if (PortInLen > 0) if (InLen > 0)
{ {
// Check duration since last PortIn // Check duration since last PortIn
Duration = TimePassed( PortInStart ); Duration = TimePassed( InStart );
if (Duration > PortInTimeout) if (Duration > InTimeout)
{ {
// Handle buffer as packet // Handle buffer as packet
PortInBuffer[ PortInLen ] = 0; InBuffer[ InLen ] = 0;
//ShowOutput( "Port", PortInBuffer, PortInLen, Duration ); //ShowOutput( "Port", InBuffer, PortInLen, Duration );
// Write output to Port // Write output to Port
BytesWritten = 0; BytesWritten = 0;
StartWrite = 0; StartWrite = 0;
while (StartWrite < PortInLen) { if (SocketHandle != -1) {
BytesWritten = write( SocketHandle, &PortInBuffer[StartWrite], PortInLen ); while (StartWrite < InLen) {
BytesWritten = write( SocketHandle, &InBuffer[StartWrite], InLen );
StartWrite += BytesWritten; StartWrite += BytesWritten;
} }
}
// Reset buffer and timer // Reset buffer and timer
PortInLen = 0; InLen = 0;
SetInterval( &PortInStart, 0 ); SetInterval( &InStart, 0 );
} }
} }
return true; return true;

View File

@@ -12,7 +12,7 @@
/* none */ /* none */
// Standard C/C++ Libraries // Standard C/C++ Libraries
/* none */ #include <sys/time.h>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -28,13 +28,36 @@
#define SW_FLOWCTRL 2 #define SW_FLOWCTRL 2
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Port Functions // Port Core Class
int OpenPort( const char * PortName ); class CPortCore
bool ClosePort(); {
bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ); private:
// Port Def
int Handle;
char * Name;
bool ReadPort(); // PortIn buffer
bool MaintainPort( int SocketHandle ); 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_ */ #endif /* PORTCORE_H_ */

View File

@@ -297,15 +297,21 @@ bool ReadClientSocket()
// Check if anything to read // Check if anything to read
ioctl( ClientHandle, FIONREAD, &SockBytesWaiting ); ioctl( ClientHandle, FIONREAD, &SockBytesWaiting );
if (SockBytesWaiting) // Test for close event
if (!SockBytesWaiting)
{ {
// Handle Incoming Data // EOF from server (close connection)
CloseTCPSocket( ctRemoteClient );
ClientHandle = -1;
return false;
}
// Check if socket ready (non-block open not in progress) // Check if socket ready (non-block open not in progress)
if (ClientState == ssWaitingtoOpen) else if (ClientState == ssWaitingtoOpen)
{ {
printf( "Socket: %s -> Cannot read from socket in waiting\n", ServerName ); printf( "Socket: %s -> Cannot read from socket in waiting\n", ServerName );
SockBytesWaiting = 0; SockBytesWaiting = 0;
} }
// Handel incoming data
else else
{ {
// Read data into buffer // Read data into buffer
@@ -329,13 +335,6 @@ bool ReadClientSocket()
SetStartTime( &SockInStart ); SetStartTime( &SockInStart );
} }
} }
}
else // if (!SockBytesWaiting)
{
// EOF from server (close connection)
CloseTCPSocket( ctRemoteClient );
ClientHandle = -1;
}
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -360,10 +359,12 @@ bool MaintainSocket( int PortHandle )
// Write output to Port // Write output to Port
BytesWritten = 0; BytesWritten = 0;
StartWrite = 0; StartWrite = 0;
if (PortHandle != -1) {
while (StartWrite < SockInLen) { while (StartWrite < SockInLen) {
BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen ); BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen );
StartWrite += BytesWritten; StartWrite += BytesWritten;
} }
}
// Reset buffer and timer // Reset buffer and timer
SockInLen = 0; SockInLen = 0;