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:
161
PortCore.cpp
161
PortCore.cpp
@@ -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;
|
||||
|
||||
// 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 );
|
||||
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;
|
||||
|
||||
37
PortCore.h
37
PortCore.h
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user