Files
redAcore/SelectableCore.h
Charl Wentzel 92db4da7de Importnant update:
- Add callback functions for change in socket states
2017-02-16 03:12:18 +02:00

275 lines
8.4 KiB
C++

/*
* SelectableCore.h
*
* Created on: 13 May 2016
* Author: wentzelc
*/
#ifndef REDACORE_SELECTABLECORE_H_
#define REDACORE_SELECTABLECORE_H_
// Standard C/C++ Libraries
#include <stdio.h>
#include <sys/wait.h>
#include <string.h>
// redA Libraries
#include "FunctionCore.h"
//---------------------------------------------------------------------------
// Types required for connections
typedef enum { ctNone = 0, ctPort = 1, ctForkPipe = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5 } EConnectType;
const char ConnectTypeName[][15] = { "None", "Port", "ForkPipe", "Server", "RemoteClient", "Client" };
typedef enum { csNone = 0, csWaitingtoOpen = 1, csOpen = 2, csDataWaiting = 3, csClosed = 4, csFailed = 5 } EConnectState;
const char ConnectStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
//---------------------------------------------------------------------------
// Defines required to configure port
#define NO_PARITY 0
#define ODD_PARITY 1
#define EVEN_PARITY 2
#define MARK_PARITY 3
#define SPACE_PARITY 4
#define NO_FLOWCTRL 0
#define HW_FLOWCTRL 1
#define SW_FLOWCTRL 2
//---------------------------------------------------------------------------
// Previews
typedef struct SSelectHandle TSelectHandle;
typedef struct SHandle THandle;
class CSelect;
class CSelectableCore;
// Callback function for handle events
typedef void (*FHandleCallback)( CSelectableCore * Function, THandle * Handle, EConnectState State );
//---------------------------------------------------------------------------
// List of Handles for Select Object
struct SSelectHandle {
// File Descriptor
int FD;
bool Read;
bool Write;
// Event Object
CSelectableCore * Function;
// List
TSelectHandle * Next;
};
//---------------------------------------------------------------------------
// List or Handles for Selectable Function Object
struct SHandle {
// Description
char * Name;
EConnectType Type;
// State
int FD;
EConnectState State;
bool Auto;
// Callback functions
FHandleCallback StateCallback[ 6 ];
// Type specific parameters
char * Path; // Port (file)name or Exec path
pid_t ChildPID; // Forked child PID
char * Address; // Socket IP address
int PortNo; // Socket port no
bool KeepAlive; // Socket keep alive
// Buffers
CBuffer * InBuffer;
CBuffer * OutBuffer;
// Input Markers
char * InMarker;
int InMarkerLen;
// Input Timer
timeval InStart;
long InTimeout; // millisecs
// Reopen Timer
timeval ReopenStart;
long ReopenTimeout; // millisecs
// List / Tree
TChannel * Channel;
THandle * Parent;
THandle * Next;
};
//---------------------------------------------------------------------------
class CSelect
{
protected:
// List
TSelectHandle * FirstHandle;
// Select Variables
fd_set ReadTestFDS;
fd_set WriteTestFDS;
fd_set ReadFDS;
fd_set WriteFDS;
// Configuration
int MaxFD;
timeval Timeout;
// Output
CLogCore * Log;
EDebugLevel DebugLevel;
public:
// Life Cycle
CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel DebugLevel );
~CSelect();
// Manage FDs
void Clear();
void Add( int FD, bool Read, bool Write, CSelectableCore * Function = NULL);
void Remove( int FD, bool Read, bool Write );
// Testing FDs
bool Test();
bool Check( int FD, bool &Read, bool &Write );
};
//---------------------------------------------------------------------------
class CSelectableCore : public CFunctionCore
{
protected:
// FDs
THandle * FirstHandle;
// Select interface
CSelect * Select;
// Managing File Handles
bool RemoveHandle( THandle * Handle );
bool DestroyHandle( THandle * Handle );
// Get Parameters
inline int GetFD( const char * HandleName ) {
THandle * Handle = GetHandle( HandleName );
return ((Handle)? Handle->FD : -1);
};
inline EConnectType GetType( const char * HandleName ) {
THandle * Handle = GetHandle( HandleName );
return ((Handle)? Handle->Type : ctNone);
};
inline EConnectState GetState( const char * HandleName ) {
THandle * Handle = GetHandle( HandleName );
return ((Handle)? Handle->State : csNone);
};
// General fucntions
inline bool ChangeState( THandle * Handle, EConnectState State ) {
if (!Handle || (Handle->State == State)) return false;
if (Handle->StateCallback[ (int)State ])
(Handle->StateCallback[ (int)State ])( this, Handle, State );
Handle->State = State;
return true;
}
// Port Operations
virtual int OpenPort( THandle * Handle );
// ForkPipe Operations
virtual int OpenForkPipe( THandle * Handle );
// Socket Operations
virtual int OpenServerSocket( THandle * Handle );
virtual int OpenRemoteClientSocket( THandle * Handle );
virtual int OpenClientSocket( THandle * Handle );
// Mutual Operations
int ReadFromFD( int FD, char * Data, int MaxLen );
int WriteToFD( int FD, const char * Data, int Len, bool Force );
// Buffer operations
virtual bool ProcessBuffer( THandle * Handle, bool Force );
// Specific operations
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] );
public:
// Life Cycle
CSelectableCore( const char * Name, CSelect * Selector, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
~CSelectableCore();
// Finding Handles
inline THandle * GetHandle( const char * HandleName )
{
if (!HandleName) return NULL;
THandle * Handle = FirstHandle;
while ( Handle && strcmp( HandleName, Handle->Name ))
Handle = Handle->Next;
return Handle;
}
inline THandle * GetHandle( int FD )
{
if (FD < 0) return NULL;
THandle * Handle = FirstHandle;
while ( Handle && (FD != Handle->FD))
Handle = Handle->Next;
return Handle;
}
// Configuration
THandle * CreateHandle( const char * HandleName, bool CreateChannel );
bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback );
bool SetAutoManage( THandle * Handle, bool AutoManage, int ReopenTime = 0 );
bool SetBuffers( THandle * Handle, int InBufSize, int OutBufSize, int InTimeout, const char * InMarker, int InMarkerLen );
bool SerialConfig( THandle * Handle, int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );
// File Interface
bool SetPortHandle( THandle * Handle, const char * FileName );
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * Address, const int PortNo, bool KeepAlive );
bool ClearHandle( THandle * Handle );
// FD Operations
virtual int Open( THandle * Handle );
virtual bool Close( THandle * Handle, bool CloseChildren = false );
virtual bool Read( THandle * Handle );
virtual bool Write( THandle * Handle );
// FD operations
inline virtual int Open( const char * HandleName ) { return (Open( GetHandle( HandleName ))); };
inline virtual bool Close( const char * HandleName, bool CloseChildren = false ) { return (Close( GetHandle( HandleName ), CloseChildren )); };
inline virtual bool Close( int FD, bool CloseChildren = false ) { return (Close( GetHandle( FD ), CloseChildren )); };
inline virtual bool Read( const char * HandleName ) { return (Read( GetHandle( HandleName ))); };
inline virtual bool Read( int FD ) { return (Read( GetHandle( FD ))); };
inline virtual bool Write( const char * HandleName ) { return (Write( GetHandle( HandleName ))); };
inline virtual bool Write( int FD ) { return (Write( GetHandle( FD ))); };
// Function Interface
virtual int Input( const char *ChannelName, const char * Buffer, int BufLen = -1 );
virtual bool Process();
};
//---------------------------------------------------------------------------
#endif /* REDACORE_SELECTABLECORE_H_ */