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