Major update:
- Converted CSocketCore to Class/Object - Implemented CFunctionCore as base class for CPortCore and CSocketCore - Moved common functions to CFunctionCore and renamed eg. Maintain() -> Process() - Pass Objects directly to each other as OutputFunction - New Input() method allows data transfer between objects
This commit is contained in:
@@ -243,7 +243,7 @@ int CBuffer::ReadFromFD( int Handle, int MaxRead )
|
|||||||
// Read from file descriptor
|
// Read from file descriptor
|
||||||
BufRemain = BufSize - BufEnd;
|
BufRemain = BufSize - BufEnd;
|
||||||
BytesRead = read( Handle, &Buffer[BufEnd], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
|
BytesRead = read( Handle, &Buffer[BufEnd], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
|
||||||
if (BytesRead <= 0)
|
if (BytesRead < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Update Buffer Pointers
|
// Update Buffer Pointers
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
PROJECT(lib_redAcore)
|
PROJECT(lib_redAcore)
|
||||||
|
|
||||||
ADD_LIBRARY(redAcore TimingCore.cpp LogCore.cpp BufferCore.cpp SignalCore.cpp PortCore.cpp SocketCore.cpp SelectCore.cpp)
|
ADD_LIBRARY(redAcore TimingCore.cpp LogCore.cpp BufferCore.cpp FunctionCore.cpp SignalCore.cpp PortCore.cpp SocketCore.cpp SelectCore.cpp)
|
||||||
|
|||||||
161
FunctionCore.cpp
Normal file
161
FunctionCore.cpp
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* FunctionCore.cpp
|
||||||
|
*
|
||||||
|
* Created on: 18 May 2016
|
||||||
|
* Author: wentzelc
|
||||||
|
*/
|
||||||
|
|
||||||
|
// redA Libraries
|
||||||
|
#include "FunctionCore.h"
|
||||||
|
#include "TimingCore.h"
|
||||||
|
#include "LogCore.h"
|
||||||
|
|
||||||
|
// Standard C/C++ Libraries
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Life cycle
|
||||||
|
CFunctionCore::CFunctionCore( const char * FunctionName )
|
||||||
|
{
|
||||||
|
// Set name
|
||||||
|
if (FunctionName) {
|
||||||
|
Name = (char*)malloc( strlen(FunctionName) );
|
||||||
|
strcpy( Name, FunctionName );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In buffer
|
||||||
|
Buffer = new CBuffer( 20 );
|
||||||
|
OutFunction = NULL;
|
||||||
|
|
||||||
|
// Input Timeout
|
||||||
|
InStart.tv_sec = 0;
|
||||||
|
InStart.tv_usec = 0;
|
||||||
|
InTimeout = 100; // millisecs
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CFunctionCore::~CFunctionCore()
|
||||||
|
{
|
||||||
|
// Destroy pointers
|
||||||
|
if (Name) {
|
||||||
|
free( Name );
|
||||||
|
}
|
||||||
|
if (Buffer) {
|
||||||
|
delete Buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Manual Data Input/Output
|
||||||
|
int CFunctionCore::Input( int InputID, char * Buffer, int MaxLen )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CFunctionCore::Output( int OutputID, char * Buffer, int Len )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Automated Data Input/Output
|
||||||
|
bool CFunctionCore::AddInput( int InputID, CFunctionCore * OutFunction, int OutputID )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CFunctionCore::AddOutput( int OutputID, CFunctionCore * InFunction, int InputID )
|
||||||
|
{
|
||||||
|
OutFunction = InFunction;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CFunctionCore::Process()
|
||||||
|
{
|
||||||
|
// Misc
|
||||||
|
long Duration = 0;
|
||||||
|
|
||||||
|
if (Buffer->Len() > 0)
|
||||||
|
{
|
||||||
|
// Check duration since last PortIn
|
||||||
|
Duration = TimePassed( InStart );
|
||||||
|
if (Duration > InTimeout)
|
||||||
|
{
|
||||||
|
// Process Input
|
||||||
|
ProcessBuffer( true );
|
||||||
|
|
||||||
|
// Reset timer
|
||||||
|
SetInterval( &InStart, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Device Interface
|
||||||
|
bool CFunctionCore::Read( int fd )
|
||||||
|
|
||||||
|
{
|
||||||
|
int BytesRead = 0;
|
||||||
|
|
||||||
|
// Read File directly into buffer
|
||||||
|
if (!(BytesRead = Buffer->ReadFromFD( fd )))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Process Buffer
|
||||||
|
ProcessBuffer( false );
|
||||||
|
|
||||||
|
// Reset timer
|
||||||
|
SetStartTime( &InStart );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CFunctionCore::Write( int fd )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CFunctionCore::WriteToFD( int FD, char * Data, int Len )
|
||||||
|
{
|
||||||
|
int BytesWritten = 0;
|
||||||
|
int TotalWritten = 0;
|
||||||
|
int DataRemain = 0;
|
||||||
|
|
||||||
|
// Check if buffer created
|
||||||
|
if ((FD == -1) || !Data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Data into buffer
|
||||||
|
DataRemain = (Len == -1)? strlen(Data) : Len;
|
||||||
|
while (DataRemain)
|
||||||
|
{
|
||||||
|
// Read from file descriptor
|
||||||
|
BytesWritten = write( FD, Data, DataRemain );
|
||||||
|
if (BytesWritten <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Update Data Pointers
|
||||||
|
TotalWritten += BytesWritten;
|
||||||
|
DataRemain -= BytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TotalWritten;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
57
FunctionCore.h
Normal file
57
FunctionCore.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* FunctionCore.h
|
||||||
|
*
|
||||||
|
* Created on: 18 May 2016
|
||||||
|
* Author: wentzelc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REDACORE_FUNCTIONCORE_H_
|
||||||
|
#define REDACORE_FUNCTIONCORE_H_
|
||||||
|
|
||||||
|
// redA Libraries
|
||||||
|
#include "BufferCore.h"
|
||||||
|
|
||||||
|
// Standard C/C++ Libraries
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CFunctionCore
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// Function Definition
|
||||||
|
char * Name;
|
||||||
|
|
||||||
|
// Input/Outputs
|
||||||
|
CBuffer * Buffer;
|
||||||
|
CFunctionCore *OutFunction;
|
||||||
|
|
||||||
|
// Input Timer
|
||||||
|
timeval InStart;
|
||||||
|
long InTimeout; // millisecs
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Life cycle
|
||||||
|
CFunctionCore( const char * ObjectName );
|
||||||
|
virtual ~CFunctionCore();
|
||||||
|
|
||||||
|
// Manual Data Input/Output
|
||||||
|
virtual int Input( int InputID, char * Buffer, int MaxLen );
|
||||||
|
virtual int Output( int OutputID, char * Buffer, int Len );
|
||||||
|
|
||||||
|
// Automated Data Input/Output
|
||||||
|
virtual bool AddInput( int InputID, CFunctionCore * OutFunction, int OutputID );
|
||||||
|
virtual bool AddOutput( int OutputID, CFunctionCore * InFunction, int InputID );
|
||||||
|
virtual bool Process();
|
||||||
|
|
||||||
|
// Device Interface
|
||||||
|
virtual bool Read( int FD );
|
||||||
|
virtual bool Write( int FD );
|
||||||
|
virtual bool ProcessBuffer( bool Force ) = 0;
|
||||||
|
|
||||||
|
int WriteToFD( int FD, char * Data, int Len );
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif /* REDACORE_FUNCTIONCORE_H_ */
|
||||||
87
PortCore.cpp
87
PortCore.cpp
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
#include "PortCore.h"
|
#include "PortCore.h"
|
||||||
#include "TimingCore.h"
|
|
||||||
#include "LogCore.h"
|
#include "LogCore.h"
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
@@ -22,46 +21,21 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CPortCore::CPortCore( const char * PortName, const int PortInBufSize )
|
CPortCore::CPortCore( const char * PortName ) :
|
||||||
|
CFunctionCore( PortName )
|
||||||
{
|
{
|
||||||
// Port File Handle
|
|
||||||
Handle = -1;
|
|
||||||
|
|
||||||
// Copy Port name
|
|
||||||
if (PortName) {
|
|
||||||
Name = (char*)malloc( strlen( PortName)+ 1);
|
|
||||||
strcpy( Name, PortName );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Name = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In buffer
|
|
||||||
Buffer = new CBuffer( PortInBufSize );
|
|
||||||
|
|
||||||
// Input Timeout
|
|
||||||
InStart.tv_sec = 0;
|
|
||||||
InStart.tv_usec = 0;
|
|
||||||
InTimeout = 100; // millisecs
|
|
||||||
|
|
||||||
// Input Markers
|
// Input Markers
|
||||||
InMarkers = NULL;
|
InMarkers = NULL;
|
||||||
InMarkerLen = 0;
|
InMarkerLen = 0;
|
||||||
|
|
||||||
// Output
|
// Port File Handle
|
||||||
OutputHandle = -1;
|
Handle = -1;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CPortCore::~CPortCore()
|
CPortCore::~CPortCore()
|
||||||
{
|
{
|
||||||
// Destroy pointers
|
// Destroy pointers
|
||||||
if (Name) {
|
|
||||||
free( Name );
|
|
||||||
}
|
|
||||||
if (Buffer) {
|
|
||||||
delete Buffer;
|
|
||||||
}
|
|
||||||
if (InMarkers) {
|
if (InMarkers) {
|
||||||
free( InMarkers );
|
free( InMarkers );
|
||||||
}
|
}
|
||||||
@@ -136,14 +110,6 @@ bool CPortCore::InputConfig( const long InputTimeout, const char * InputMarkers,
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Configure output options
|
|
||||||
bool CPortCore::OutputConfig( int PortOutputHandle )
|
|
||||||
{
|
|
||||||
OutputHandle = PortOutputHandle;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Set serial port configuration parameters
|
// Set serial port configuration parameters
|
||||||
bool CPortCore::SerialConfig( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait )
|
bool CPortCore::SerialConfig( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait )
|
||||||
{
|
{
|
||||||
@@ -283,21 +249,9 @@ bool CPortCore::SerialConfig( int Baud, short DataBits, short StopBits, short Pa
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CPortCore::Read( const int MaxRead )
|
int CPortCore::Input( int InputID, char * Data, int Len )
|
||||||
{
|
{
|
||||||
int BytesRead = 0;
|
return WriteToFD( Handle, Data, Len );
|
||||||
|
|
||||||
// Read File directly into buffer
|
|
||||||
if (!(BytesRead = Buffer->ReadFromFD( Handle )))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Process Buffer
|
|
||||||
ProcessBuffer( false );
|
|
||||||
|
|
||||||
// Reset timer
|
|
||||||
SetStartTime( &InStart );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -320,7 +274,8 @@ bool CPortCore::ProcessBuffer( bool Force )
|
|||||||
ShowOutput( "Port In", OUT_NORMAL, Data, Len );
|
ShowOutput( "Port In", OUT_NORMAL, Data, Len );
|
||||||
|
|
||||||
// Write buffer to Port
|
// Write buffer to Port
|
||||||
Buffer->WriteToFD( OutputHandle, Len );
|
if (OutFunction)
|
||||||
|
OutFunction->Input( 0, Data, Len );
|
||||||
|
|
||||||
// Clear processed bytes from buffer
|
// Clear processed bytes from buffer
|
||||||
Buffer->Clear( Len );
|
Buffer->Clear( Len );
|
||||||
@@ -335,7 +290,8 @@ bool CPortCore::ProcessBuffer( bool Force )
|
|||||||
ShowOutput( "Port In", OUT_NORMAL, Data, Len );
|
ShowOutput( "Port In", OUT_NORMAL, Data, Len );
|
||||||
|
|
||||||
// Write buffer to Port
|
// Write buffer to Port
|
||||||
Buffer->WriteToFD( OutputHandle, Len );
|
if (OutFunction)
|
||||||
|
OutFunction->Input( 0, Data, Len );
|
||||||
|
|
||||||
// Clear processed bytes from buffer
|
// Clear processed bytes from buffer
|
||||||
Buffer->Clear( Len );
|
Buffer->Clear( Len );
|
||||||
@@ -345,26 +301,3 @@ bool CPortCore::ProcessBuffer( bool Force )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CPortCore::Maintain()
|
|
||||||
{
|
|
||||||
// Misc
|
|
||||||
long Duration = 0;
|
|
||||||
|
|
||||||
if (Buffer->Len() > 0)
|
|
||||||
{
|
|
||||||
// Check duration since last PortIn
|
|
||||||
Duration = TimePassed( InStart );
|
|
||||||
if (Duration > InTimeout)
|
|
||||||
{
|
|
||||||
// Process Input
|
|
||||||
ProcessBuffer( true );
|
|
||||||
|
|
||||||
// Reset timer
|
|
||||||
SetInterval( &InStart, 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|||||||
36
PortCore.h
36
PortCore.h
@@ -9,10 +9,10 @@
|
|||||||
#define REDACORE_PORTCORE_H_
|
#define REDACORE_PORTCORE_H_
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
#include "BufferCore.h"
|
#include "FunctionCore.h"
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <sys/time.h>
|
/* none */
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -29,41 +29,29 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Port Core Class
|
// Port Core Class
|
||||||
class CPortCore
|
class CPortCore : public CFunctionCore
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
// Port Def
|
|
||||||
int Handle;
|
|
||||||
char * Name;
|
|
||||||
|
|
||||||
// Port Buffer
|
|
||||||
CBuffer * Buffer;
|
|
||||||
|
|
||||||
// Input Timer
|
|
||||||
timeval InStart;
|
|
||||||
long InTimeout; // millisecs
|
|
||||||
|
|
||||||
// Input Markers
|
// Input Markers
|
||||||
char * InMarkers;
|
char * InMarkers;
|
||||||
int InMarkerLen;
|
int InMarkerLen;
|
||||||
|
|
||||||
// Output
|
// Device Interfaces
|
||||||
int OutputHandle;
|
int Handle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPortCore( const char * PortName, const int PortInBufSize );
|
CPortCore( const char * PortName );
|
||||||
~CPortCore();
|
virtual ~CPortCore();
|
||||||
|
|
||||||
bool Open();
|
bool Open();
|
||||||
bool Close();
|
bool Close();
|
||||||
bool InputConfig( long InputTimeout, const char * InputMarkers, int InputMarkerLen );
|
bool InputConfig( long InputTimeout, const char * InputMarkers, int InputMarkerLen );
|
||||||
bool SerialConfig( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );
|
bool SerialConfig( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );
|
||||||
bool OutputConfig( int PortOutputHandle );
|
int GetPortFD() { return Handle; };
|
||||||
int GetHandle() { return Handle; };
|
|
||||||
|
|
||||||
bool Read( int MaxRead );
|
virtual int Input( int InputID, char * Buffer, int BufLen );
|
||||||
bool Maintain();
|
|
||||||
bool ProcessBuffer( bool Force );
|
virtual bool ProcessBuffer( bool Force );
|
||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
186
SocketCore.cpp
186
SocketCore.cpp
@@ -29,38 +29,31 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Variables
|
CSocketCore::CSocketCore( const char * ServerName ) :
|
||||||
char * ServerName = NULL;
|
CFunctionCore( ServerName )
|
||||||
char ServerAddress[25] = "";
|
{
|
||||||
int PortNo = 0;
|
ServerAddress[0] = 0;
|
||||||
char ClientAddress[25] = "";
|
PortNo = 0;
|
||||||
|
ClientAddress[0] = 0;
|
||||||
|
|
||||||
int ServerHandle = -1;
|
ServerHandle = -1;
|
||||||
ESocketState ServerState = ssNone;
|
ServerState = ssNone;
|
||||||
|
|
||||||
int ClientHandle = -1;
|
|
||||||
ESocketState ClientState = ssNone;
|
|
||||||
|
|
||||||
char SockInBuffer[500] = "";
|
|
||||||
int SockInBufLen = 500;
|
|
||||||
int SockInLen = 0;
|
|
||||||
|
|
||||||
// SockIn Timer
|
|
||||||
timeval SockInStart = { 0, 0 };
|
|
||||||
long SockInTimeout = 100; // millisecs
|
|
||||||
|
|
||||||
int SockBytesRead = 0;
|
|
||||||
int SockBytesWaiting = 0;
|
|
||||||
|
|
||||||
|
ClientHandle = -1;
|
||||||
|
ClientState = ssNone;
|
||||||
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, bool KeepAlive )
|
CSocketCore::~CSocketCore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CSocketCore::OpenTCPserverSocket( const char *pAddress, int pPortNo, bool KeepAlive )
|
||||||
{
|
{
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
|
|
||||||
ServerName = (char*)malloc( strlen(pName)+1 );
|
|
||||||
strcpy( ServerName, pName );
|
|
||||||
strcpy( ServerAddress, pAddress );
|
strcpy( ServerAddress, pAddress );
|
||||||
PortNo = pPortNo;
|
PortNo = pPortNo;
|
||||||
|
|
||||||
@@ -87,7 +80,7 @@ int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, b
|
|||||||
// Create socket
|
// Create socket
|
||||||
if ((ServerHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
if ((ServerHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
{
|
{
|
||||||
printf( "Server Socket: %s [%d] -> Failed to create server socket (%s)\n", ServerName, PortNo, strerror(errno) );
|
printf( "Server Socket: %s [%d] -> Failed to create server socket (%s)\n", Name, PortNo, strerror(errno) );
|
||||||
ServerState = ssFailed;
|
ServerState = ssFailed;
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
@@ -96,7 +89,7 @@ int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, b
|
|||||||
if ((setsockopt( ServerHandle, SOL_SOCKET, SO_LINGER, &ServerLinger_opt, sizeof(ServerLinger_opt)) == -1) ||
|
if ((setsockopt( ServerHandle, SOL_SOCKET, SO_LINGER, &ServerLinger_opt, sizeof(ServerLinger_opt)) == -1) ||
|
||||||
(setsockopt( ServerHandle, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1))
|
(setsockopt( ServerHandle, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1))
|
||||||
{
|
{
|
||||||
printf( "Server Socket: %s [%d] -> Could not set socket options (%s)\n", ServerName, PortNo, strerror(errno) );
|
printf( "Server Socket: %s [%d] -> Could not set socket options (%s)\n", Name, PortNo, strerror(errno) );
|
||||||
ServerState = ssFailed;
|
ServerState = ssFailed;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -108,7 +101,7 @@ int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, b
|
|||||||
(setsockopt( ServerHandle, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) ||
|
(setsockopt( ServerHandle, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) ||
|
||||||
(setsockopt( ServerHandle, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
|
(setsockopt( ServerHandle, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
|
||||||
{
|
{
|
||||||
printf( "Server Socket: %s [%d] -> Could not set socket keepalive options (%s)\n", ServerName, PortNo, strerror(errno) );
|
printf( "Server Socket: %s [%d] -> Could not set socket keepalive options (%s)\n", Name, PortNo, strerror(errno) );
|
||||||
ServerState = ssFailed;
|
ServerState = ssFailed;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -116,7 +109,7 @@ int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, b
|
|||||||
// Bind socket
|
// Bind socket
|
||||||
if (bind( ServerHandle, (struct sockaddr *)&address, addr_len ) < 0)
|
if (bind( ServerHandle, (struct sockaddr *)&address, addr_len ) < 0)
|
||||||
{
|
{
|
||||||
printf( "Server Socket: %s [%d] -> Failed to bind server to socket (%s)\n", ServerName, PortNo, strerror(errno) );
|
printf( "Server Socket: %s [%d] -> Failed to bind server to socket (%s)\n", Name, PortNo, strerror(errno) );
|
||||||
close( ServerHandle );
|
close( ServerHandle );
|
||||||
ServerState = ssFailed;
|
ServerState = ssFailed;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -125,7 +118,7 @@ int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, b
|
|||||||
// Create que for 5 connections
|
// Create que for 5 connections
|
||||||
if (listen( ServerHandle, 5 ) < 0)
|
if (listen( ServerHandle, 5 ) < 0)
|
||||||
{
|
{
|
||||||
printf( "Server Socket: %s [%d] -> Failed to create server socket listen que (%s)\n", ServerName, PortNo, strerror(errno) );
|
printf( "Server Socket: %s [%d] -> Failed to create server socket listen que (%s)\n", Name, PortNo, strerror(errno) );
|
||||||
close( ServerHandle );
|
close( ServerHandle );
|
||||||
ServerState = ssFailed;
|
ServerState = ssFailed;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -133,12 +126,12 @@ int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, b
|
|||||||
|
|
||||||
// Server open
|
// Server open
|
||||||
ServerState = ssOpen;
|
ServerState = ssOpen;
|
||||||
printf( "Server Socket: %s [%d] -> Socket binded and listening\n", ServerName, PortNo );
|
printf( "Server Socket: %s [%d] -> Socket binded and listening\n", Name, PortNo );
|
||||||
return ServerHandle;
|
return ServerHandle;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int OpenTCPinClientSocket()
|
int CSocketCore::OpenTCPinClientSocket()
|
||||||
{
|
{
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
@@ -152,9 +145,9 @@ int OpenTCPinClientSocket()
|
|||||||
if ((ClientHandle = accept( ServerHandle, (struct sockaddr *)&address, &addr_len)) == -1)
|
if ((ClientHandle = accept( ServerHandle, (struct sockaddr *)&address, &addr_len)) == -1)
|
||||||
{
|
{
|
||||||
if (errno == EWOULDBLOCK)
|
if (errno == EWOULDBLOCK)
|
||||||
printf( "Remote Socket: %s [*] -> Failed to accept blocking connection (%s)\n", ServerName, strerror(errno) );
|
printf( "Remote Socket: %s [*] -> Failed to accept blocking connection (%s)\n", Name, strerror(errno) );
|
||||||
else
|
else
|
||||||
printf( "Remote Socket: %s [*] -> Failed to accept connection (%s)\n", ServerName, strerror(errno) );
|
printf( "Remote Socket: %s [*] -> Failed to accept connection (%s)\n", Name, strerror(errno) );
|
||||||
close( ClientHandle );
|
close( ClientHandle );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -162,7 +155,7 @@ int OpenTCPinClientSocket()
|
|||||||
// Return client address
|
// Return client address
|
||||||
strcpy( ClientAddress, inet_ntoa(address.sin_addr) );
|
strcpy( ClientAddress, inet_ntoa(address.sin_addr) );
|
||||||
ClientState = ssOpen;
|
ClientState = ssOpen;
|
||||||
printf( "Remote Socket: %s -> Server accepted connection from client (%s)\n", ServerName, ClientAddress );
|
printf( "Remote Socket: %s -> Server accepted connection from client (%s)\n", Name, ClientAddress );
|
||||||
}
|
}
|
||||||
else if (ClientState == ssWaitingtoOpen)
|
else if (ClientState == ssWaitingtoOpen)
|
||||||
{
|
{
|
||||||
@@ -171,7 +164,7 @@ int OpenTCPinClientSocket()
|
|||||||
fcntl( ClientHandle, F_SETFL, (!O_NONBLOCK)&flags );
|
fcntl( ClientHandle, F_SETFL, (!O_NONBLOCK)&flags );
|
||||||
|
|
||||||
// Log event
|
// Log event
|
||||||
printf( "Socket: %s -> Client now connected to server (%s)\n", ServerName, ServerAddress );
|
printf( "Socket: %s -> Client now connected to server (%s)\n", Name, ServerAddress );
|
||||||
|
|
||||||
// Trigger handler & set new state
|
// Trigger handler & set new state
|
||||||
ClientState = ssOpen;
|
ClientState = ssOpen;
|
||||||
@@ -181,13 +174,11 @@ int OpenTCPinClientSocket()
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int OpenTCPoutClientSocket( const char *pName, const char *pAddress, int pPortNo, bool KeepAlive )
|
int CSocketCore::OpenTCPoutClientSocket( const char *pAddress, int pPortNo, bool KeepAlive )
|
||||||
{
|
{
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
|
|
||||||
ServerName = (char*)malloc( strlen(pName)+1 );
|
|
||||||
strcpy( ServerName, pName );
|
|
||||||
strcpy( ServerAddress, pAddress );
|
strcpy( ServerAddress, pAddress );
|
||||||
PortNo = pPortNo;
|
PortNo = pPortNo;
|
||||||
|
|
||||||
@@ -203,7 +194,7 @@ int OpenTCPoutClientSocket( const char *pName, const char *pAddress, int pPortNo
|
|||||||
// Create File descriptor
|
// Create File descriptor
|
||||||
if ((ClientHandle = socket( AF_INET, SOCK_STREAM, 0 )) < 0)
|
if ((ClientHandle = socket( AF_INET, SOCK_STREAM, 0 )) < 0)
|
||||||
{
|
{
|
||||||
printf( "Client Socket: %s [*] -> Failed to create Client Socket (%s)\n", ServerName, strerror(errno) );
|
printf( "Client Socket: %s [*] -> Failed to create Client Socket (%s)\n", Name, strerror(errno) );
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -218,7 +209,7 @@ int OpenTCPoutClientSocket( const char *pName, const char *pAddress, int pPortNo
|
|||||||
(setsockopt( ClientHandle, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) ||
|
(setsockopt( ClientHandle, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) ||
|
||||||
(setsockopt( ClientHandle, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
|
(setsockopt( ClientHandle, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
|
||||||
{
|
{
|
||||||
printf( "Client Socket: %s -> Could not set socket keepalive options (%s)\n", ServerName, strerror(errno) );
|
printf( "Client Socket: %s -> Could not set socket keepalive options (%s)\n", Name, strerror(errno) );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +233,7 @@ int OpenTCPoutClientSocket( const char *pName, const char *pAddress, int pPortNo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf( "Client Socket: %s -> Client failed to connect (%s)\n", ServerName, strerror(errno) );
|
printf( "Client Socket: %s -> Client failed to connect (%s)\n", Name, strerror(errno) );
|
||||||
|
|
||||||
// Set status
|
// Set status
|
||||||
ClientState = ssFailed;
|
ClientState = ssFailed;
|
||||||
@@ -255,7 +246,7 @@ int OpenTCPoutClientSocket( const char *pName, const char *pAddress, int pPortNo
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Delete socket
|
// Delete socket
|
||||||
bool CloseTCPSocket( ESockConnectType SocketType )
|
bool CSocketCore::CloseTCPSocket( ESockConnectType SocketType )
|
||||||
{
|
{
|
||||||
bool Fail;
|
bool Fail;
|
||||||
|
|
||||||
@@ -272,20 +263,20 @@ bool CloseTCPSocket( ESockConnectType SocketType )
|
|||||||
switch (SocketType)
|
switch (SocketType)
|
||||||
{
|
{
|
||||||
case ctServer:
|
case ctServer:
|
||||||
printf( "Server Socket: %s -> Server %s\n", ServerName, ((Fail)? "failed" : "closed") );
|
printf( "Server Socket: %s -> Server %s\n", Name, ((Fail)? "failed" : "closed") );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ctRemoteClient:
|
case ctRemoteClient:
|
||||||
printf( "Remote Client: %s -> Connection to client %s\n", ServerName, ((Fail)? "failed" : "closed") );
|
printf( "Remote Client: %s -> Connection to client %s\n", Name, ((Fail)? "failed" : "closed") );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ctClient:
|
case ctClient:
|
||||||
printf( "Client Socket: %s -> Connection to server %s\n", ServerName, ((Fail)? "failed" : "closed") );
|
printf( "Client Socket: %s -> Connection to server %s\n", Name, ((Fail)? "failed" : "closed") );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ctNone:
|
case ctNone:
|
||||||
default:
|
default:
|
||||||
printf( "Socket : %s -> Cannot %s socket (invalid socket type)\n", ServerName, ((Fail)? "fail" : "close") );
|
printf( "Socket : %s -> Cannot %s socket (invalid socket type)\n", Name, ((Fail)? "fail" : "close") );
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -293,10 +284,19 @@ bool CloseTCPSocket( ESockConnectType SocketType )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ReadClientSocket()
|
int CSocketCore::Input( int InputID, char * Data, int Len )
|
||||||
{
|
{
|
||||||
|
return WriteToFD( ClientHandle, Data, Len );
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CSocketCore::Read( int FD )
|
||||||
|
{
|
||||||
|
int SockBytesRead = 0;
|
||||||
|
int SockBytesWaiting = 0;
|
||||||
|
|
||||||
// Check if anything to read
|
// Check if anything to read
|
||||||
ioctl( ClientHandle, FIONREAD, &SockBytesWaiting );
|
ioctl( FD, FIONREAD, &SockBytesWaiting );
|
||||||
|
|
||||||
// Test for close event
|
// Test for close event
|
||||||
if (!SockBytesWaiting)
|
if (!SockBytesWaiting)
|
||||||
@@ -309,69 +309,71 @@ bool ReadClientSocket()
|
|||||||
// Check if socket ready (non-block open not in progress)
|
// Check if socket ready (non-block open not in progress)
|
||||||
else 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", Name );
|
||||||
SockBytesWaiting = 0;
|
SockBytesWaiting = 0;
|
||||||
}
|
}
|
||||||
// Handel incoming data
|
// Handle incoming data
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Read data into buffer
|
// Read data from socket
|
||||||
SockBytesRead = read( ClientHandle, &SockInBuffer[SockInLen], SockBytesWaiting ); // SockInBufLen-SockInLen
|
if (!(SockBytesRead = Buffer->ReadFromFD( FD, SockBytesWaiting ))) {
|
||||||
|
return false;
|
||||||
// Check of errors
|
|
||||||
if (SockBytesRead == -1)
|
|
||||||
{
|
|
||||||
printf( "Socket: %s -> Cannot read from socket (%s)\n", ServerName, strerror(errno) );
|
|
||||||
SockBytesRead = 0;
|
|
||||||
|
|
||||||
// Check of non-blocking write
|
|
||||||
// bool Blocked = ((errno == EAGAIN)? true : false );
|
|
||||||
}
|
}
|
||||||
else if (SockBytesRead > 0)
|
|
||||||
{
|
|
||||||
// Process Reply
|
|
||||||
SockInLen += SockBytesRead;
|
|
||||||
|
|
||||||
// Reset timer
|
// Process Buffer
|
||||||
SetStartTime( &SockInStart );
|
ProcessBuffer( false );
|
||||||
}
|
|
||||||
|
// Start timer
|
||||||
|
SetStartTime( &InStart );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool MaintainSocket( int PortHandle )
|
bool CSocketCore::ProcessBuffer( bool Force )
|
||||||
{
|
{
|
||||||
// Init vars
|
int Pos = 0;
|
||||||
long Duration = 0;
|
int Len = 0;
|
||||||
int BytesWritten = 0;
|
char * Data = NULL;
|
||||||
int StartWrite = 0;
|
|
||||||
|
|
||||||
if (SockInLen > 0)
|
// Check if buffered data
|
||||||
|
if (!Buffer->Len()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if forced processed
|
||||||
|
if (Force)
|
||||||
{
|
{
|
||||||
// Check duration since last PortIn
|
// Show Packet
|
||||||
Duration = TimePassed( SockInStart );
|
Len = Buffer->Peek( &Data );
|
||||||
if (Duration > SockInTimeout)
|
ShowOutput( "Port In", OUT_NORMAL, Data, Len );
|
||||||
|
|
||||||
|
// Write buffer to Port
|
||||||
|
if (OutFunction)
|
||||||
|
OutFunction->Input( 0, Data, Len );
|
||||||
|
|
||||||
|
// Clear processed bytes from buffer
|
||||||
|
Buffer->Clear( Len );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Search for end of packet marker
|
||||||
|
while (Buffer->FindChar( '\n', Pos ))
|
||||||
{
|
{
|
||||||
// Handle buffer as packet
|
// Show Packet
|
||||||
SockInBuffer[ SockInLen ] = 0;
|
Len = Buffer->Peek( &Data, 0, Pos+1 );
|
||||||
ShowOutput( "Sock In", OUT_NORMAL|OUT_HEX, SockInBuffer, SockInLen );
|
ShowOutput( "Port In", OUT_NORMAL, Data, Len );
|
||||||
|
|
||||||
// Write output to Port
|
// Write buffer to Port
|
||||||
BytesWritten = 0;
|
if (OutFunction)
|
||||||
StartWrite = 0;
|
OutFunction->Input( 0, Data, Len );
|
||||||
if (PortHandle != -1) {
|
|
||||||
while (StartWrite < SockInLen) {
|
|
||||||
BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen );
|
|
||||||
StartWrite += BytesWritten;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset buffer and timer
|
// Clear processed bytes from buffer
|
||||||
SockInLen = 0;
|
Buffer->Clear( Len );
|
||||||
SetInterval( &SockInStart, 0 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
44
SocketCore.h
44
SocketCore.h
@@ -9,7 +9,7 @@
|
|||||||
#define REDACORE_SOCKETCORE_H_
|
#define REDACORE_SOCKETCORE_H_
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
/* none */
|
#include "FunctionCore.h"
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
/* none */
|
/* none */
|
||||||
@@ -24,19 +24,43 @@ typedef enum { ssNone = 0, ssWaitingtoOpen = 1, ssOpen = 2, ssDataWaiting = 3, s
|
|||||||
const char SocketStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
const char SocketStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Socket Functions
|
// Port Core Class
|
||||||
int OpenTCPserverSocket( const char *pServerName, const char *ServerAddress, int PortNo, bool KeepAlive );
|
class CSocketCore : public CFunctionCore
|
||||||
int OpenTCPinClientSocket();
|
{
|
||||||
int OpenTCPoutClientSocket( const char *pServerName, const char *ServerAddress, int PortNo, bool KeepAlive );
|
protected:
|
||||||
|
char ServerAddress[25];
|
||||||
|
int PortNo;
|
||||||
|
char ClientAddress[25];
|
||||||
|
|
||||||
ESocketState GetServerState();
|
int ServerHandle;
|
||||||
ESocketState GetClientState();
|
ESocketState ServerState;
|
||||||
|
|
||||||
bool CloseTCPSocket( ESockConnectType SocketType );
|
int ClientHandle;
|
||||||
|
ESocketState ClientState;
|
||||||
|
|
||||||
bool ReadClientSocket();
|
public:
|
||||||
bool MaintainSocket( int PortHandle );
|
// Life Cycle
|
||||||
|
CSocketCore( const char * ServerName );
|
||||||
|
virtual ~CSocketCore();
|
||||||
|
|
||||||
|
// Socket Functions
|
||||||
|
int OpenTCPserverSocket( const char *ServerAddress, int PortNo, bool KeepAlive );
|
||||||
|
int OpenTCPinClientSocket();
|
||||||
|
int OpenTCPoutClientSocket( const char *ServerAddress, int PortNo, bool KeepAlive );
|
||||||
|
|
||||||
|
ESocketState GetServerState();
|
||||||
|
ESocketState GetClientState();
|
||||||
|
|
||||||
|
bool CloseTCPSocket( ESockConnectType SocketType );
|
||||||
|
|
||||||
|
int GetServerFD() { return ServerHandle; };
|
||||||
|
int GetClientFD() { return ClientHandle; };
|
||||||
|
|
||||||
|
virtual int Input( int InputID, char * Buffer, int BufLen );
|
||||||
|
|
||||||
|
virtual bool Read( int FD );
|
||||||
|
virtual bool ProcessBuffer( bool Force );
|
||||||
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif /* REDACORE_SOCKETCORE_H_ */
|
#endif /* REDACORE_SOCKETCORE_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user