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:
163
PortCore.cpp
163
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 );
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user