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
#include "TimingCore.h"
#include "PortCore.h"
#include "TimingCore.h"
// Standard C/C++ Libraries
#include <stdio.h>
@@ -21,68 +21,93 @@
//---------------------------------------------------------------------------
// Port Def
int PortHandle = -1;
char * PortName = NULL;
CPortCore::CPortCore( const char * PortName, const int PortInBufLen ) : InBufLen( PortInBufLen )
{
// Port File Handle
Handle = -1;
// PortIn buffer
char PortInBuffer[500] = "";
int PortInBufLen = 500;
int PortInLen = 0;
int PortBytesRead = 0;
// Copy Port name
if (PortName) {
Name = (char*)malloc( strlen( PortName)+ 1);
strcpy( Name, PortName );
}
else {
Name = NULL;
}
// PortIn Timer
timeval PortInStart = { 0, 0 };
long PortInTimeout = 100; // millisecs
// In buffer
InBuffer = (char *)malloc( InBufLen );
InLen = 0;
BytesRead = 0;
// In buffer Timer
InStart.tv_sec = 0;
InStart.tv_usec = 0;
InTimeout = 100; // millisecs
}
//---------------------------------------------------------------------------
int OpenPort( const char * pPortName )
CPortCore::~CPortCore()
{
// Copy Port name
PortName = (char*)malloc( strlen(pPortName)+ 1);
strcpy( PortName, pPortName );
// Destroy pointers
if (Name) {
free( Name );
}
}
//---------------------------------------------------------------------------
bool CPortCore::Open()
{
// Check if valid port name
if (!Name) {
return false;
}
// Check if port exits
if (access( PortName, F_OK ) != 0)
if (access( Name, F_OK ) != 0)
{
printf( "Port: %s -> Could not find port\n", PortName );
return -1;
printf( "Port: %s -> Could not find port\n", Name );
return false;
}
// Open Port
PortHandle = open( PortName, O_RDWR );
if (PortHandle == -1)
Handle = open( Name, O_RDWR );
if (Handle == -1)
{
printf( "Port: %s -> Could not open port\n", PortName );
return -1;
printf( "Port: %s -> Could not open port\n", Name );
return false;
}
// Confirm open
printf( "Port: %s -> Port opened\n", PortName );
return PortHandle;
printf( "Port: %s -> Port opened\n", Name );
return true;
}
//---------------------------------------------------------------------------
bool ClosePort()
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 );
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;

View File

@@ -12,7 +12,7 @@
/* none */
// Standard C/C++ Libraries
/* none */
#include <sys/time.h>
//---------------------------------------------------------------------------
@@ -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_ */

View File

@@ -297,15 +297,21 @@ bool ReadClientSocket()
// Check if anything to read
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)
if (ClientState == ssWaitingtoOpen)
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
@@ -329,13 +335,6 @@ bool ReadClientSocket()
SetStartTime( &SockInStart );
}
}
}
else // if (!SockBytesWaiting)
{
// EOF from server (close connection)
CloseTCPSocket( ctRemoteClient );
ClientHandle = -1;
}
return true;
}
//---------------------------------------------------------------------------
@@ -360,10 +359,12 @@ bool MaintainSocket( int PortHandle )
// Write output to Port
BytesWritten = 0;
StartWrite = 0;
if (PortHandle != -1) {
while (StartWrite < SockInLen) {
BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen );
StartWrite += BytesWritten;
}
}
// Reset buffer and timer
SockInLen = 0;