Major Update:
- Implement new ApplicationCore:
- Manage Tools: Log, DataTree, JSONparser & Selector
- Load configuration, Manage FunctionBlocks
- FunctionCore & dirived classes, SignalCore:
- affects: SelectableCore, DeviceCore, FileCore, WatchdogCore
- Do not pass Log()
- Define and pass Type
- Update/reduce included headers
- Use ProcessName and Application global vars
- Get Log, DataTree from Application
- Use virtual Init() function to set must have Channels/Handles
- DataTreeCore:
- Bug fix: Check if child members exist and destroy in SetValuePtr()
- Add method GetFirstChild with BaseMember & Path
- Bug fix: do not use RootMember if no Parent in GetChildxxx() methods
- SignalCore, SelectCore:
- Use Application->Log()
- FunctionCore:
- Add itself to Application (function list)
- Add parameter: LinkConfigMember, Type
- Use virtual LoadConfigData() to configure from DataTree
- Rename methods: LoadConfig() -> InitConfig(),
InitLogging() -> SetLogParam(), SetDebugLevel() -> SetLogLevel()
- Add method: GetType(), LoadChannelLinkData(), InitChannelLinks()
- Modify LinkIn/OutputChannel() to use name for InFunction, not pointer
- SelectableCore & Dirived classes:
- Affects DeviceCore & WatchdogClient
- Rename parameter: Select -> Selector, BaseMember -> ConfigMember
- Get Selector from Application->Selector
- Change Handles JSON structure from Array to Key:Value pairs
- Bug fix: check if Selector exist during Input()
- Bug fix: do not set PortNo if not exist
This commit is contained in:
370
ApplicationCore.cpp
Normal file
370
ApplicationCore.cpp
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* FunctionListCore.cpp
|
||||
*
|
||||
* Created on: 12 Jul 2017
|
||||
* Author: wentzelc
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "WatchdogCore.h"
|
||||
#include "FileCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Global Vars
|
||||
extern char * ProcessName;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CApplication::CApplication( EDebugLevel pLogLevel )
|
||||
{
|
||||
// Set signal handlers
|
||||
ConfigureSignalHandlers();
|
||||
|
||||
// Variables used for configuration
|
||||
ConfigMember = NULL;
|
||||
FunctionConfigMember = NULL;
|
||||
LinkConfigMember = NULL;
|
||||
|
||||
ConfigFile = NULL;
|
||||
AddressFile = NULL;
|
||||
|
||||
// Create output logger
|
||||
Log = new CLogCore( stdout );
|
||||
LogLevel = pLogLevel;
|
||||
LogOutput = OUT_NORMAL;
|
||||
|
||||
// Create Configuration
|
||||
DataTree = new CDataTree();
|
||||
ConfigParser = new CJSONparse( DataTree );
|
||||
|
||||
// Selector
|
||||
Selector = NULL;
|
||||
|
||||
// List
|
||||
FirstFunction = NULL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CApplication::~CApplication()
|
||||
{
|
||||
TFunctionItem * NextFunction;
|
||||
|
||||
if (FirstFunction)
|
||||
{
|
||||
// Show Start of termination
|
||||
if (Log) Log->Message( dlLow, dlLow, "%s: Terminating...", ProcessName );
|
||||
|
||||
// Destroy functions
|
||||
while (FirstFunction)
|
||||
{
|
||||
NextFunction = FirstFunction->Next;
|
||||
delete( FirstFunction->Function );
|
||||
free( FirstFunction );
|
||||
FirstFunction = NextFunction;
|
||||
}
|
||||
}
|
||||
|
||||
// Show Completion
|
||||
if (Log) Log->Message( dlLow, dlLow, "%s: Terminated.", ProcessName );
|
||||
|
||||
// Destroy tools
|
||||
if (Selector) delete Selector;
|
||||
if (Log) delete Log;
|
||||
if (DataTree) delete DataTree;
|
||||
if (ConfigParser) delete ConfigParser;
|
||||
|
||||
// Free Process Name
|
||||
if (ProcessName) free( ProcessName );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CApplication::GetProcessName( char ** ProcessName, char * pFilePath )
|
||||
{
|
||||
char * TempStr;
|
||||
|
||||
// Remove Path
|
||||
TempStr = strrchr( pFilePath, '/' );
|
||||
if (TempStr[0] == '/') TempStr++;
|
||||
|
||||
// Copy Process Name
|
||||
*ProcessName = (char*)malloc( strlen(TempStr)+1 );
|
||||
strcpy( *ProcessName, TempStr );
|
||||
|
||||
// Remove extension
|
||||
TempStr = strrchr( *ProcessName, '.' );
|
||||
if (TempStr) TempStr[0] = 0;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::LoadConfig( int argc, char *argv[], const char * pConfigPath )
|
||||
{
|
||||
// Read Parameters
|
||||
if ((argc != 2))
|
||||
{
|
||||
// Get Process Name
|
||||
GetProcessName( &ProcessName, argv[0] );
|
||||
|
||||
// Incorrect no of parameters, show correct usage
|
||||
printf( "%s: Incorrect number of parameters\n", ProcessName );
|
||||
printf( " usage: %s [ConfigFile]\n\n", ProcessName );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load parameters
|
||||
GetProcessName( &ProcessName, argv[1] );
|
||||
ConfigFile = argv[1];
|
||||
}
|
||||
|
||||
// Load Application List
|
||||
if (ConfigParser->ReadFromFile( pConfigPath, ConfigFile )) {
|
||||
if (Log) Log->Message( dlLow, dlLow, "%s: Config file loaded (%s)", ProcessName, ConfigFile );
|
||||
} else {
|
||||
if (Log) Log->Message( dlLow, dlLow, "%s: Fail to load config file (%s)- %s", ProcessName, ConfigFile, ConfigParser->GetError() );
|
||||
return false;
|
||||
}
|
||||
//ConfigParser->WriteToScreen( pConfigPath, 2 );
|
||||
|
||||
// Loaded successfully
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::SaveConfig()
|
||||
{
|
||||
// Save updated configuration
|
||||
if (ConfigFile && *ConfigFile)
|
||||
ConfigParser->WriteToFile( "config", ConfigFile );
|
||||
if (AddressFile && *AddressFile )
|
||||
ConfigParser->WriteToFile( "address", AddressFile );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::LoadConfigData()
|
||||
{
|
||||
TDataMember * TempMember;
|
||||
EDebugLevel pLogLevel;
|
||||
int pLogOutput;
|
||||
char * TempStr;
|
||||
|
||||
// Get debug level
|
||||
pLogLevel = dlNone;
|
||||
TempStr = (char*)DataTree->GetStr( ConfigMember, "Log/Level", "Medium", true );
|
||||
if (TempStr)
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Low" ))
|
||||
pLogLevel = dlLow;
|
||||
else if (!strcasecmp( TempStr, "Medium" ))
|
||||
pLogLevel = dlMedium;
|
||||
else if (!strcasecmp( TempStr, "High" ))
|
||||
pLogLevel = dlHigh;
|
||||
}
|
||||
|
||||
// Set debug output
|
||||
pLogOutput = 0;
|
||||
TempMember = DataTree->GetFirstChild( ConfigMember, "Log/Output", true );
|
||||
while (TempMember)
|
||||
{
|
||||
if (TempMember->Value)
|
||||
{
|
||||
if (!strcasecmp( TempMember->Value, "Normal"))
|
||||
pLogOutput |= OUT_NORMAL;
|
||||
else if (!strcasecmp( TempMember->Value, "Bin"))
|
||||
pLogOutput |= OUT_BIN;
|
||||
else if (!strcasecmp( TempMember->Value, "Hex"))
|
||||
pLogOutput |= OUT_HEX;
|
||||
else if (!strcasecmp( TempMember->Value, "Count"))
|
||||
pLogOutput |= OUT_COUNT;
|
||||
else if (!strcasecmp( TempMember->Value, "AsIs"))
|
||||
pLogOutput |= OUT_ASIS;
|
||||
else if (!strcasecmp( TempMember->Value, "CRLF"))
|
||||
pLogOutput |= OUT_CRLF;
|
||||
}
|
||||
|
||||
// Next
|
||||
TempMember = DataTree->GetNextChild( TempMember );
|
||||
}
|
||||
SetLogParam( pLogLevel, pLogOutput );
|
||||
|
||||
// Load Address List
|
||||
if ((AddressFile = (char*)DataTree->GetStr( ConfigMember, "AddressList/Path", NULL )))
|
||||
{
|
||||
if (ConfigParser->ReadFromFile( "address", AddressFile )) {
|
||||
if (Log) Log->Message( dlLow, dlLow, "%s: Address file loaded (%s)", ProcessName, AddressFile );
|
||||
} else {
|
||||
if (Log) Log->Message( dlLow, dlLow, "%s: Fail to load Address file (%s) - %s", ProcessName, AddressFile, ConfigParser->GetError() );
|
||||
}
|
||||
//ConfigParser->WriteToScreen( pAddressListPath, 2 );
|
||||
}
|
||||
|
||||
// Configure Selector
|
||||
if ((TempMember = DataTree->GetMember( ConfigMember, "Selector" )))
|
||||
{
|
||||
// Create Selector
|
||||
Selector = new CSelect( (int)DataTree->GetInt( TempMember, "Wait", 5, true ), LogLevel );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay )
|
||||
{
|
||||
// Output
|
||||
LogLevel = pDebugLevel;
|
||||
LogOutput = pOutputDisplay;
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::Init()
|
||||
{
|
||||
// Report status
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Application Initialised", ProcessName );
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::InitConfig( const char * pConfigPath )
|
||||
{
|
||||
// Check if Datatree exists
|
||||
if (!DataTree || !(ConfigMember = DataTree->GetMember( NULL, pConfigPath ))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// LoadConfiguration
|
||||
LoadConfigData();
|
||||
Init();
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::InitFunctions( const char * pConfigPath )
|
||||
{
|
||||
CFunctionCore * Function;
|
||||
TDataMember * TempMember;
|
||||
char * Type;
|
||||
|
||||
// Check of path exists
|
||||
if (!DataTree || !(FunctionConfigMember = DataTree->GetMember( NULL, pConfigPath )))
|
||||
return false;
|
||||
|
||||
// Process each Channel
|
||||
TempMember = DataTree->GetFirstChild( FunctionConfigMember );
|
||||
while (TempMember)
|
||||
{
|
||||
// Get function parameters
|
||||
Type = (char*)DataTree->GetStr( TempMember, "Type", "Custom", true );
|
||||
|
||||
// Get or create function
|
||||
if (!strcasecmp( Type, "WatchdogClient" )) {
|
||||
Function = new CWatchdogCore( TempMember->Name );
|
||||
}
|
||||
else if (!strcasecmp( Type, "Selectable" )) {
|
||||
Function = new CSelectableCore( TempMember->Name );
|
||||
}
|
||||
else if (!strcasecmp( Type, "File" )) {
|
||||
Function = new CFileCore( TempMember->Name );
|
||||
}
|
||||
else {
|
||||
Function = GetFunction( TempMember->Name );
|
||||
}
|
||||
|
||||
// Load Function configuration and Initialise
|
||||
if (Function) {
|
||||
Function->InitConfig( TempMember );
|
||||
}
|
||||
|
||||
// Next
|
||||
TempMember = TempMember->Next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::InitFunctionLinks( const char * pConfigPath )
|
||||
{
|
||||
TFunctionItem * FunctionItem;
|
||||
TDataMember * TempMember;
|
||||
|
||||
// Check of path exists
|
||||
if (!DataTree || !(LinkConfigMember = DataTree->GetMember( NULL, pConfigPath )))
|
||||
return false;
|
||||
|
||||
// Process each Channel
|
||||
FunctionItem = FirstFunction;
|
||||
while (FunctionItem)
|
||||
{
|
||||
// Build links for function
|
||||
if ((TempMember = DataTree->GetMember( LinkConfigMember, FunctionItem->Function->GetName() )))
|
||||
FunctionItem->Function->InitChannelLinks( TempMember );
|
||||
|
||||
// Next
|
||||
FunctionItem = FunctionItem->Next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Build List
|
||||
bool CApplication::AddFunction( CFunctionCore * Function )
|
||||
{
|
||||
TFunctionItem ** FunctionPtr;
|
||||
|
||||
// Check if unique, else get end of list
|
||||
FunctionPtr = &FirstFunction;
|
||||
while (*FunctionPtr && strcasecmp( (*FunctionPtr)->Function->GetName(), Function->GetName() ))
|
||||
FunctionPtr = &((*FunctionPtr)->Next);
|
||||
|
||||
// Check if exists
|
||||
if (*FunctionPtr)
|
||||
return false;
|
||||
|
||||
// Add to end of list
|
||||
*FunctionPtr = (TFunctionItem*)calloc( sizeof(TFunctionItem), 1 );
|
||||
(*FunctionPtr)->Function = Function;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Search List
|
||||
CFunctionCore * CApplication::GetFunction( const char * Name )
|
||||
{
|
||||
TFunctionItem * FunctionItem;
|
||||
|
||||
// Find in list
|
||||
FunctionItem = FirstFunction;
|
||||
while (FunctionItem && strcasecmp( FunctionItem->Function->GetName(), Name ))
|
||||
FunctionItem = FunctionItem->Next;
|
||||
|
||||
return ((FunctionItem)? FunctionItem->Function : NULL);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CApplication::Run()
|
||||
{
|
||||
TFunctionItem * FunctionItem;
|
||||
|
||||
// Check for FD Events/States
|
||||
if (Selector) {
|
||||
Selector->Test();
|
||||
}
|
||||
|
||||
// Process Functions
|
||||
for (FunctionItem = FirstFunction; FunctionItem; FunctionItem = FunctionItem->Next )
|
||||
FunctionItem->Function->Process();
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
99
ApplicationCore.h
Normal file
99
ApplicationCore.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Application.h
|
||||
*
|
||||
* Created on: 13 Jul 2017
|
||||
* Author: wentzelc
|
||||
*/
|
||||
|
||||
#ifndef REDACORE_APPLICATIONCORE_H_
|
||||
#define REDACORE_APPLICATIONCORE_H_
|
||||
|
||||
// redA Libraries
|
||||
#include "SignalCore.h"
|
||||
#include "TimingCore.h"
|
||||
#include "LogCore.h"
|
||||
#include "DataTreeCore.h"
|
||||
#include "JSONparseCore.h"
|
||||
#include "FunctionCore.h"
|
||||
#include "SelectableCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Preview
|
||||
typedef struct SFunctionItem TFunctionItem;
|
||||
|
||||
class Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
struct SFunctionItem
|
||||
{
|
||||
CFunctionCore * Function;
|
||||
|
||||
SFunctionItem * Next;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class CApplication
|
||||
{
|
||||
protected:
|
||||
// Variables used for configuration
|
||||
char * ConfigFile;
|
||||
char * AddressFile;
|
||||
|
||||
// List
|
||||
TFunctionItem * FirstFunction;
|
||||
|
||||
// Configuration
|
||||
CJSONparse * ConfigParser = NULL;
|
||||
|
||||
// Output
|
||||
EDebugLevel LogLevel;
|
||||
int LogOutput;
|
||||
|
||||
// Configuration
|
||||
TDataMember * ConfigMember;
|
||||
TDataMember * FunctionConfigMember;
|
||||
TDataMember * LinkConfigMember;
|
||||
|
||||
bool LoadConfigData();
|
||||
|
||||
public:
|
||||
// Public function vars
|
||||
CDataTree * DataTree;
|
||||
CLogCore * Log;
|
||||
CSelect * Selector;
|
||||
|
||||
// Life Cycle
|
||||
CApplication( EDebugLevel pDebugLevel );
|
||||
virtual ~CApplication();
|
||||
|
||||
// Manage Config File
|
||||
void GetProcessName( char ** ProcessName, char * pFilePath );
|
||||
bool LoadConfig( int argc, char *argv[], const char * pConfigPath );
|
||||
bool SaveConfig();
|
||||
|
||||
// Manually set configuration
|
||||
bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay );
|
||||
|
||||
// Init application
|
||||
virtual bool Init();
|
||||
|
||||
bool InitConfig( const char * pConfigPath );
|
||||
bool InitFunctions( const char * pConfigPath );
|
||||
bool InitFunctionLinks( const char * pConfigPath );
|
||||
|
||||
// Manage Functions
|
||||
bool AddFunction( CFunctionCore * Function );
|
||||
CFunctionCore * GetFunction( const char * Name );
|
||||
|
||||
// Run Application
|
||||
bool Run();
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#endif /* REDACORE_APPLICATIONCORE_H_ */
|
||||
@@ -1,3 +1,4 @@
|
||||
PROJECT(lib_redAcore)
|
||||
|
||||
ADD_LIBRARY(redAcore TimingCore.cpp DateTimeCore.cpp LogCore.cpp SignalCore.cpp DataTreeCore.cpp JSONparseCore.cpp BufferCore.cpp LiteProtocolCore.cpp FunctionCore.cpp WatchdogCore.cpp DeviceCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp)
|
||||
ADD_LIBRARY(redAcore TimingCore.cpp DateTimeCore.cpp LogCore.cpp SignalCore.cpp DataTreeCore.cpp JSONparseCore.cpp BufferCore.cpp LiteProtocolCore.cpp
|
||||
ApplicationCore.cpp FunctionCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp WatchdogCore.cpp DeviceCore.cpp )
|
||||
|
||||
@@ -273,28 +273,6 @@ TDataMember * CDataTree::GetMember( TDataMember * BaseMember, const char * Path
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TDataMember * CDataTree::GetFirstChild( TDataMember * Parent )
|
||||
{
|
||||
// Get Parent
|
||||
if (!Parent)
|
||||
Parent = RootMember;
|
||||
|
||||
// Return child
|
||||
return Parent->FirstChild;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TDataMember * CDataTree::GetNextChild( TDataMember * PrevChild )
|
||||
{
|
||||
// Validate
|
||||
if (!PrevChild)
|
||||
return NULL;
|
||||
|
||||
// Return next child
|
||||
return PrevChild->Next;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TDataMember * CDataTree::GetIndexChild( TDataMember * Parent, const int Index )
|
||||
{
|
||||
TDataMember * Child;
|
||||
@@ -302,7 +280,7 @@ TDataMember * CDataTree::GetIndexChild( TDataMember * Parent, const int Index )
|
||||
|
||||
// Get Parent
|
||||
if (!Parent)
|
||||
Parent = RootMember;
|
||||
return NULL;
|
||||
|
||||
// Get Indexed child
|
||||
Count = 0;
|
||||
@@ -317,6 +295,20 @@ TDataMember * CDataTree::GetIndexChild( TDataMember * Parent, const int Index )
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TDataMember * CDataTree::GetFirstChild( TDataMember * BaseMember, const char * Path, bool Create )
|
||||
{
|
||||
TDataMember * Member;
|
||||
|
||||
// Validate
|
||||
if (!(Member = GetMember( BaseMember, Path, Create ))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return child
|
||||
return Member->FirstChild;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
|
||||
{
|
||||
TDataMember * Parent;
|
||||
@@ -357,7 +349,7 @@ bool CDataTree::DeleteAll()
|
||||
bool CDataTree::SetValuePtr( TDataMember * Member, EDataType Type, char * Value, int Len )
|
||||
{
|
||||
// Clear previous value
|
||||
if (Member->Value != NULL) {
|
||||
if (Member->Value != NULL || (Member->FirstChild != NULL)) {
|
||||
DestroyValue( Member );
|
||||
}
|
||||
|
||||
|
||||
@@ -68,9 +68,11 @@ public:
|
||||
EDataType GetType( TDataMember * BaseMember, const char * Path );
|
||||
TDataMember * GetMember( TDataMember * BaseMember, const char * Path, bool Create = false );
|
||||
|
||||
TDataMember * GetFirstChild( TDataMember * Parent );
|
||||
TDataMember * GetNextChild( TDataMember * PrevChild );
|
||||
TDataMember * GetIndexChild( TDataMember * Parent, const int Index );
|
||||
TDataMember * GetIndexChild( TDataMember * Parent, const int Index );
|
||||
TDataMember * GetFirstChild( TDataMember * Parent, const char * Path, bool Create = false );
|
||||
|
||||
inline TDataMember * GetFirstChild( TDataMember * Parent ) { return ((Parent)? Parent->FirstChild : NULL); };
|
||||
inline TDataMember * GetNextChild( TDataMember * PrevChild ) { return ((PrevChild)? PrevChild->Next : NULL); };
|
||||
|
||||
const char * GetStr( TDataMember * BaseMember, const char * Path, const char * Default = NULL, bool Create = false );
|
||||
const char * GetStr( TDataMember * BaseMember, const char * Path, int &Len, const char * Default = NULL, bool Create = false );
|
||||
|
||||
@@ -16,15 +16,19 @@
|
||||
#include <unistd.h>
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "DeviceCore.h"
|
||||
#include "FunctionCore.h"
|
||||
#include "TimingCore.h"
|
||||
#include "LogCore.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CDeviceCore::CDeviceCore( const char * pName, CLogCore * pLog ) :
|
||||
CFunctionCore( pName, pLog )
|
||||
// Global Vars
|
||||
//extern char * ProcessName;
|
||||
//extern CApplication * Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CDeviceCore::CDeviceCore( const char * pName, const char * pType ) :
|
||||
CFunctionCore( pName, pType )
|
||||
{
|
||||
// Clear Parameters
|
||||
FirstDevice = NULL;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "FunctionCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
/* no additional */
|
||||
/* none */
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -168,7 +168,7 @@ protected:
|
||||
|
||||
public:
|
||||
// Life cycle
|
||||
CDeviceCore( const char * pName, CLogCore * pLog );
|
||||
CDeviceCore( const char * pName, const char * Type = "Device" );
|
||||
virtual ~CDeviceCore();
|
||||
|
||||
// Generate events
|
||||
|
||||
13
FileCore.cpp
13
FileCore.cpp
@@ -6,10 +6,8 @@
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "FileCore.h"
|
||||
#include "FunctionCore.h"
|
||||
#include "TimingCore.h"
|
||||
#include "LogCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
@@ -22,13 +20,14 @@
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Constants
|
||||
const float PI = 3.1415927;
|
||||
// Global Vars
|
||||
//extern char * ProcessName;
|
||||
//extern CApplication * Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CFileCore::CFileCore( const char * pName, CLogCore * pLog ) :
|
||||
CFunctionCore( pName, pLog )
|
||||
CFileCore::CFileCore( const char * pName, const char * pType ) :
|
||||
CFunctionCore( pName, pType )
|
||||
{
|
||||
FirstFile = NULL;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
|
||||
public:
|
||||
// Life cycle
|
||||
CFileCore( const char * pName, CLogCore * pLog );
|
||||
CFileCore( const char * pName, const char * pType = "File" );
|
||||
virtual ~CFileCore();
|
||||
|
||||
// Manage files
|
||||
|
||||
236
FunctionCore.cpp
236
FunctionCore.cpp
@@ -6,9 +6,8 @@
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "FunctionCore.h"
|
||||
#include "TimingCore.h"
|
||||
#include "LogCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
@@ -17,12 +16,14 @@
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
extern char * ProcessName;
|
||||
// Global Vars
|
||||
extern char * ProcessName;
|
||||
extern CApplication * Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Life cycle
|
||||
CFunctionCore::CFunctionCore( const char * pName, CLogCore * pLog )
|
||||
CFunctionCore::CFunctionCore( const char * pName, const char * pType )
|
||||
{
|
||||
// Set name
|
||||
if (pName) {
|
||||
@@ -33,17 +34,30 @@ CFunctionCore::CFunctionCore( const char * pName, CLogCore * pLog )
|
||||
Name = NULL;
|
||||
}
|
||||
|
||||
// Data Tree
|
||||
DataTree = NULL;
|
||||
BaseMember = NULL;
|
||||
// Set Type
|
||||
if (pType) {
|
||||
Type = (char*)malloc( strlen(pType)+1 );
|
||||
strcpy( Type, pType );
|
||||
}
|
||||
else {
|
||||
Type = NULL;
|
||||
}
|
||||
|
||||
// Channels
|
||||
FirstChannel = NULL;
|
||||
|
||||
// List
|
||||
Application->AddFunction( this );
|
||||
|
||||
// Data Tree
|
||||
DataTree = Application->DataTree;
|
||||
ConfigMember = NULL;
|
||||
LinkConfigMember = NULL;
|
||||
|
||||
// Output
|
||||
Log = pLog;
|
||||
LogLevel = dlNone;
|
||||
LogOutput = OUT_NORMAL;
|
||||
Log = Application->Log;
|
||||
LogLevel = dlNone;
|
||||
LogOutput = OUT_NORMAL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -90,75 +104,50 @@ CFunctionCore::~CFunctionCore()
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Destroyed", ProcessName, Name );
|
||||
|
||||
// Destroy Name
|
||||
if (Name) {
|
||||
free( Name );
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::LoadConfig( CDataTree * pDataTree, const char * pBasePath )
|
||||
{
|
||||
// Validate
|
||||
if (!(DataTree = pDataTree) || !(BaseMember = DataTree->GetMember( NULL, pBasePath, true )))
|
||||
return false;
|
||||
|
||||
// Load configuration
|
||||
LoadConfigData();
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::LoadConfig( CDataTree * pDataTree, TDataMember * pBaseMember )
|
||||
{
|
||||
// Validate
|
||||
if (!(DataTree = pDataTree) || !(BaseMember = pBaseMember ))
|
||||
return false;
|
||||
|
||||
// Load configuration
|
||||
LoadConfigData();
|
||||
|
||||
return true;
|
||||
if (Name) free( Name );
|
||||
if (Type) free( Type );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::LoadConfigData()
|
||||
{
|
||||
TDataMember * TempMember;
|
||||
EDebugLevel pLogLevel;
|
||||
int pLogOutput;
|
||||
char * TempStr;
|
||||
|
||||
// Get debug level
|
||||
LogLevel = dlNone;
|
||||
TempStr = (char*)DataTree->GetStr( BaseMember, "Log/Level", "Medium", true );
|
||||
pLogLevel = dlNone;
|
||||
TempStr = (char*)DataTree->GetStr( ConfigMember, "Log/Level", "Medium", true );
|
||||
if (TempStr)
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Low" ))
|
||||
LogLevel = dlLow;
|
||||
pLogLevel = dlLow;
|
||||
else if (!strcasecmp( TempStr, "Medium" ))
|
||||
LogLevel = dlMedium;
|
||||
pLogLevel = dlMedium;
|
||||
else if (!strcasecmp( TempStr, "High" ))
|
||||
LogLevel = dlHigh;
|
||||
pLogLevel = dlHigh;
|
||||
}
|
||||
|
||||
// Set debug output
|
||||
LogOutput = 0;
|
||||
TempMember = DataTree->GetMember( BaseMember, "Log/Output[0]", true );
|
||||
pLogOutput = 0;
|
||||
TempMember = DataTree->GetFirstChild( ConfigMember, "Log/Output", true );
|
||||
while (TempMember)
|
||||
{
|
||||
if (TempMember->Value)
|
||||
{
|
||||
if (!strcasecmp( TempMember->Value, "Normal"))
|
||||
LogOutput |= OUT_NORMAL;
|
||||
pLogOutput |= OUT_NORMAL;
|
||||
else if (!strcasecmp( TempMember->Value, "Bin"))
|
||||
LogOutput |= OUT_BIN;
|
||||
pLogOutput |= OUT_BIN;
|
||||
else if (!strcasecmp( TempMember->Value, "Hex"))
|
||||
LogOutput |= OUT_HEX;
|
||||
pLogOutput |= OUT_HEX;
|
||||
else if (!strcasecmp( TempMember->Value, "Count"))
|
||||
LogOutput |= OUT_COUNT;
|
||||
pLogOutput |= OUT_COUNT;
|
||||
else if (!strcasecmp( TempMember->Value, "AsIs"))
|
||||
LogOutput |= OUT_ASIS;
|
||||
pLogOutput |= OUT_ASIS;
|
||||
else if (!strcasecmp( TempMember->Value, "CRLF"))
|
||||
LogOutput |= OUT_CRLF;
|
||||
pLogOutput |= OUT_CRLF;
|
||||
}
|
||||
|
||||
// Next
|
||||
@@ -166,15 +155,17 @@ bool CFunctionCore::LoadConfigData()
|
||||
}
|
||||
|
||||
// Set Logging
|
||||
InitLogging( LogLevel, LogOutput );
|
||||
SetLogParam( pLogLevel, pLogOutput );
|
||||
|
||||
// Set debug output
|
||||
TempMember = DataTree->GetFirstChild( DataTree->GetMember( BaseMember, "Channels" ) );
|
||||
// Load Channels
|
||||
TempMember = DataTree->GetFirstChild( ConfigMember, "Channels", true );
|
||||
while (TempMember)
|
||||
{
|
||||
AddChannel( DataTree->GetStr( TempMember, "Name" ),
|
||||
DataTree->GetBool( TempMember, "InputEnabled", true, true ),
|
||||
DataTree->GetBool( TempMember, "OutputEnabled", false, true ));
|
||||
if (TempMember->Name) {
|
||||
AddChannel( TempMember->Name,
|
||||
DataTree->GetBool( TempMember, "InputEnabled", true, true ),
|
||||
DataTree->GetBool( TempMember, "OutputEnabled", false, true ));
|
||||
}
|
||||
|
||||
// Next
|
||||
TempMember = DataTree->GetNextChild( TempMember );
|
||||
@@ -184,20 +175,112 @@ bool CFunctionCore::LoadConfigData()
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::InitLogging( EDebugLevel pDebugLevel, int pOutputDisplay )
|
||||
bool CFunctionCore::LoadChannelLinkData()
|
||||
{
|
||||
// Output
|
||||
LogLevel = pDebugLevel;
|
||||
LogOutput = pOutputDisplay;
|
||||
TChannel * Channel;
|
||||
TDataMember * ChannelMember;
|
||||
TDataMember * FunctionMember;
|
||||
|
||||
// Report status
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Created", ProcessName, Name );
|
||||
// Process each Channel
|
||||
ChannelMember = DataTree->GetFirstChild( LinkConfigMember );
|
||||
while (ChannelMember)
|
||||
{
|
||||
if ((Channel = GetChannel( ChannelMember->Name )))
|
||||
{
|
||||
FunctionMember = DataTree->GetFirstChild( ChannelMember );
|
||||
while (FunctionMember)
|
||||
{
|
||||
// Get Parameters
|
||||
LinkOutputChannel( Channel->Name,
|
||||
DataTree->GetStr( FunctionMember, "Function" ),
|
||||
DataTree->GetStr( FunctionMember, "Channel" ),
|
||||
DataTree->GetBool( FunctionMember, "Bidirectional" ) );
|
||||
// Next
|
||||
FunctionMember = DataTree->GetNextChild( FunctionMember );
|
||||
}
|
||||
}
|
||||
// Next
|
||||
ChannelMember = DataTree->GetNextChild( ChannelMember );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::SetDebugLevel( EDebugLevel pDebugLevel )
|
||||
bool CFunctionCore::Init()
|
||||
{
|
||||
// Report status
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Initialised", ProcessName, Name );
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::InitConfig( const char * pConfigPath )
|
||||
{
|
||||
// Validate
|
||||
if (!DataTree || !(ConfigMember = DataTree->GetMember( NULL, pConfigPath, true )))
|
||||
return false;
|
||||
|
||||
// Load configuration
|
||||
LoadConfigData();
|
||||
Init();
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::InitConfig( TDataMember * pBaseMember )
|
||||
{
|
||||
// Validate
|
||||
if (!DataTree || !(ConfigMember = pBaseMember ))
|
||||
return false;
|
||||
|
||||
// Load configuration
|
||||
LoadConfigData();
|
||||
Init();
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::InitChannelLinks( const char * pLinkConfigPath )
|
||||
{
|
||||
// Validate
|
||||
if (!DataTree || !(LinkConfigMember = DataTree->GetMember( NULL, pLinkConfigPath, true )))
|
||||
return false;
|
||||
|
||||
// Load configuration
|
||||
LoadChannelLinkData();
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::InitChannelLinks( TDataMember *pLinkConfigMember )
|
||||
{
|
||||
// Validate
|
||||
if (!DataTree || !(LinkConfigMember = pLinkConfigMember))
|
||||
return false;
|
||||
|
||||
// Load configuration
|
||||
LoadChannelLinkData();
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay )
|
||||
{
|
||||
// Output
|
||||
LogLevel = pDebugLevel;
|
||||
LogOutput = pOutputDisplay;
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::SetLogLevel( EDebugLevel pDebugLevel )
|
||||
{
|
||||
LogLevel = pDebugLevel;
|
||||
return true;
|
||||
@@ -242,13 +325,14 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Automated Data Input/Output
|
||||
bool CFunctionCore::LinkInputChannel( const char * ChannelName, CFunctionCore * OutFunction, const char * OutChannelName, bool Bidirectional )
|
||||
bool CFunctionCore::LinkInputChannel( const char * ChannelName, const char * OutFunctionName, const char * OutChannelName, bool Bidirectional )
|
||||
{
|
||||
CFunctionCore * OutFunction = NULL;
|
||||
TChannel * Channel = NULL;
|
||||
TChannelLink ** LinkedChannel = NULL;
|
||||
|
||||
// Get Channel
|
||||
if (!OutFunction || !OutFunction || !(Channel = GetChannel( ChannelName ))) {
|
||||
if (!(OutFunction = Application->GetFunction( OutFunctionName )) || !(Channel = GetChannel( ChannelName ))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -276,25 +360,29 @@ bool CFunctionCore::LinkInputChannel( const char * ChannelName, CFunctionCore *
|
||||
|
||||
// Link Return direction as well
|
||||
if (Bidirectional) {
|
||||
return OutFunction->LinkInputChannel( OutChannelName, this, ChannelName, false );
|
||||
return OutFunction->LinkInputChannel( OutChannelName, Name, ChannelName, false );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CFunctionCore::LinkOutputChannel( const char * ChannelName, CFunctionCore * InFunction, const char * InChannelName, bool Bidirectional )
|
||||
bool CFunctionCore::LinkOutputChannel( const char * ChannelName, const char * InFunctionName, const char * InChannelName, bool Bidirectional )
|
||||
{
|
||||
TChannel * Channel = NULL;
|
||||
TChannel * OutChannel = NULL;
|
||||
CFunctionCore * InFunction = NULL;
|
||||
TChannel * InChannel = NULL;
|
||||
TChannelLink ** LinkedChannel = NULL;
|
||||
|
||||
// Get Channel
|
||||
if (!InFunction || !InChannelName || !(Channel = GetChannel( ChannelName ))) {
|
||||
// Check if Channels & Function exist
|
||||
if (!(OutChannel = GetChannel( ChannelName )) ||
|
||||
!(InFunction = Application->GetFunction( InFunctionName )) ||
|
||||
!(InChannel = InFunction->GetChannel( InChannelName )) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if linked Channel exists
|
||||
LinkedChannel = &(Channel->FirstOutput);
|
||||
LinkedChannel = &(OutChannel->FirstOutput);
|
||||
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, InChannelName ) )) {
|
||||
LinkedChannel = &((*LinkedChannel)->Next);
|
||||
}
|
||||
@@ -317,7 +405,7 @@ bool CFunctionCore::LinkOutputChannel( const char * ChannelName, CFunctionCore *
|
||||
|
||||
// Link return direction as well
|
||||
if (Bidirectional) {
|
||||
return InFunction->LinkOutputChannel( InChannelName, this, ChannelName, false );
|
||||
return InFunction->LinkOutputChannel( InChannelName, Name, ChannelName, false );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Preview
|
||||
typedef struct SChannel TChannel;
|
||||
typedef struct SChannelLink TChannelLink;
|
||||
typedef struct SChannel TChannel;
|
||||
typedef struct SChannelLink TChannelLink;
|
||||
|
||||
class CFunctionCore;
|
||||
|
||||
@@ -55,10 +55,12 @@ class CFunctionCore
|
||||
protected:
|
||||
// Function Definition
|
||||
char * Name;
|
||||
char * Type;
|
||||
|
||||
// Configuration
|
||||
CDataTree * DataTree;
|
||||
TDataMember * BaseMember;
|
||||
TDataMember * ConfigMember;
|
||||
TDataMember * LinkConfigMember;
|
||||
|
||||
// Channels
|
||||
TChannel * FirstChannel;
|
||||
@@ -77,27 +79,34 @@ protected:
|
||||
return Channel;
|
||||
}
|
||||
|
||||
// Load configuraiton
|
||||
// Load configuration
|
||||
virtual bool LoadConfigData();
|
||||
virtual bool LoadChannelLinkData();
|
||||
|
||||
// Manual Data Input/Output
|
||||
virtual int Output( const TChannel * Channel, const char * Data, int Len );
|
||||
|
||||
public:
|
||||
// Life cycle
|
||||
CFunctionCore( const char * pName, CLogCore * pLog );
|
||||
CFunctionCore( const char * pName, const char * Type );
|
||||
virtual ~CFunctionCore();
|
||||
|
||||
// Load Configuration
|
||||
virtual bool LoadConfig( CDataTree * pDataTree, const char * pBasePath );
|
||||
virtual bool LoadConfig( CDataTree * pDataTree, TDataMember * pBaseMember );
|
||||
virtual bool Init();
|
||||
|
||||
bool InitConfig( const char * pConfigPath );
|
||||
bool InitConfig( TDataMember * pConfigMember );
|
||||
|
||||
bool InitChannelLinks( const char * pLinkConfigPath );
|
||||
bool InitChannelLinks( TDataMember *pLinkConfigMember );
|
||||
|
||||
// Set Parameters Manually
|
||||
bool InitLogging( EDebugLevel pDebugLevel, int pOutputDisplay );
|
||||
bool SetDebugLevel( EDebugLevel pDebugLevel );
|
||||
bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay );
|
||||
bool SetLogLevel( EDebugLevel pDebugLevel );
|
||||
|
||||
// Miscellaneous
|
||||
inline const char * GetName() { return Name; };
|
||||
inline const char * GetType() { return Type; };
|
||||
|
||||
// Manage Channels
|
||||
virtual TChannel * AddChannel( const char * ChannelName, const bool pInputEnable = true, const bool pOutputEnabled = true );
|
||||
@@ -127,8 +136,8 @@ public:
|
||||
virtual int Output( const char * ChannelName, const char * Data, int Len = -1 );
|
||||
|
||||
// Automated Data Input/Output
|
||||
virtual bool LinkInputChannel( const char * ChannelName, CFunctionCore * OutFunction, const char * OutChannelName, bool Bidirectional );
|
||||
virtual bool LinkOutputChannel( const char * ChannelName, CFunctionCore * InFunction, const char * InChannelName, bool Bidirectional );
|
||||
virtual bool LinkInputChannel( const char * ChannelName, const char * OutFunctionName, const char * OutChannelName, bool Bidirectional );
|
||||
virtual bool LinkOutputChannel( const char * ChannelName, const char * InFunctionName, const char * InChannelName, bool Bidirectional );
|
||||
virtual bool Process() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "SelectableCore.h"
|
||||
#include "TimingCore.h"
|
||||
#include "LogCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
@@ -18,12 +17,14 @@
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
extern char * ProcessName;
|
||||
// Global Vars
|
||||
extern char * ProcessName;
|
||||
extern CApplication * Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Create Select
|
||||
CSelect::CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pDebugLevel )
|
||||
CSelect::CSelect( long SelectTimeout, EDebugLevel pDebugLevel )
|
||||
{
|
||||
// Clear List
|
||||
FirstHandle = NULL;
|
||||
@@ -39,11 +40,11 @@ CSelect::CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pDebugLevel )
|
||||
SetInterval( &Timeout, SelectTimeout );
|
||||
|
||||
// Output
|
||||
Log = pLog;
|
||||
Log = Application->Log;
|
||||
LogLevel = pDebugLevel;
|
||||
|
||||
// Show status
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Select - Created", ProcessName );
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Selector - Created", ProcessName );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -61,7 +62,7 @@ CSelect::~CSelect()
|
||||
}
|
||||
|
||||
// Show status
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Select - Destroyed", ProcessName );
|
||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Selector - Destroyed", ProcessName );
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -113,7 +114,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
||||
FD_SET( FD, &ReadTestFDS );
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Select: FD [%d] - Add Read", FD );
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Selector: FD [%d] - Add Read", FD );
|
||||
}
|
||||
|
||||
// Add Write Select
|
||||
@@ -122,7 +123,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
||||
FD_SET( FD, &WriteTestFDS );
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Select: FD [%d] - Add Write", FD );
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Selector: FD [%d] - Add Write", FD );
|
||||
}
|
||||
|
||||
// Check Maximum File Handle
|
||||
@@ -150,7 +151,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
|
||||
FD_CLR( FD, &ReadTestFDS);
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Select: FD [%d] - Remove Read", FD );
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Selector: FD [%d] - Remove Read", FD );
|
||||
}
|
||||
|
||||
// Remove from set for select write check
|
||||
@@ -159,7 +160,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
|
||||
FD_CLR( FD, &WriteTestFDS);
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Select: FD [%d] - Remove Write", FD );
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Selector: FD [%d] - Remove Write", FD );
|
||||
}
|
||||
// Handle will be removed in Test() if both Read & Write flags are false
|
||||
}
|
||||
@@ -181,7 +182,7 @@ bool CSelect::Test()
|
||||
Events = select( MaxFD, &ReadFDS, &WriteFDS, (fd_set*)NULL, &STimeout );
|
||||
if (Events < 0)
|
||||
{
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Select: Select operation failed" );
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "Selector: Select operation failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "SelectableCore.h"
|
||||
#include "TimingCore.h"
|
||||
#include "LogCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
@@ -30,14 +29,20 @@
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CSelectableCore::CSelectableCore( const char * pName, CSelect * pSelect, CLogCore * pLog ) :
|
||||
CFunctionCore( pName, pLog )
|
||||
// Global Vars
|
||||
//extern char * ProcessName;
|
||||
extern CApplication * Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CSelectableCore::CSelectableCore( const char * pName, const char * pType ) :
|
||||
CFunctionCore( pName, pType )
|
||||
{
|
||||
// Quick access
|
||||
Selector = Application->Selector;
|
||||
|
||||
// Handles
|
||||
FirstHandle = NULL;
|
||||
|
||||
// Select
|
||||
Select = pSelect;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -73,13 +78,17 @@ bool CSelectableCore::LoadConfigData()
|
||||
// Call Previous load config
|
||||
CFunctionCore::LoadConfigData();
|
||||
|
||||
// Set debug output
|
||||
TempMember = DataTree->GetFirstChild( DataTree->GetMember( BaseMember, "Handles", true ) );
|
||||
// Load Handles
|
||||
TempMember = DataTree->GetFirstChild( DataTree->GetMember( ConfigMember, "Handles", true ) );
|
||||
while (TempMember)
|
||||
{
|
||||
// Check if name is valid
|
||||
if (!TempMember->Name || !*TempMember->Name)
|
||||
continue;
|
||||
|
||||
// Create Handle and channel link
|
||||
Handle = CreateHandle( DataTree->GetStr( TempMember, "Name" ), false );
|
||||
Handle->Channel = GetChannel( DataTree->GetStr( TempMember, "Name" ) );
|
||||
Handle = CreateHandle( TempMember->Name, false );
|
||||
Handle->Channel = GetChannel( DataTree->GetStr( TempMember, "Channel" ) );
|
||||
|
||||
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
||||
if (!strcasecmp( Type, "Port" ))
|
||||
@@ -94,7 +103,7 @@ bool CSelectableCore::LoadConfigData()
|
||||
else if (!strcasecmp( Type, "TCPserver" ))
|
||||
{
|
||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
|
||||
Port = DataTree->GetInt( TempMember, "Socket/Port", 0, true ); // Get default Port value
|
||||
Port = DataTree->GetInt( TempMember, "Socket/Port", 0 ); // Get default Port value
|
||||
if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
|
||||
sprintf( Path, "Address/%s/Address", Name );
|
||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
|
||||
@@ -106,7 +115,7 @@ bool CSelectableCore::LoadConfigData()
|
||||
else if (!strcasecmp( Type, "TCPclient" ))
|
||||
{
|
||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
|
||||
Port = DataTree->GetInt( TempMember, "Socket/Port", 0, true ); // Get default Port value
|
||||
Port = DataTree->GetInt( TempMember, "Socket/Port", 0 ); // Get default Port value
|
||||
if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
|
||||
sprintf( Path, "Address/%s/Address", Name );
|
||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
|
||||
@@ -435,8 +444,8 @@ int CSelectableCore::OpenPort( THandle * Handle )
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port opened [%s]", Name, Handle->Name, Handle->Path );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( Handle->FD, true, false, this );
|
||||
if (Selector) {
|
||||
Selector->Add( Handle->FD, true, false, this );
|
||||
}
|
||||
|
||||
// Set state
|
||||
@@ -527,8 +536,8 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
|
||||
}
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( Handle->FD, false, true, this );
|
||||
if (Selector) {
|
||||
Selector->Add( Handle->FD, false, true, this );
|
||||
}
|
||||
|
||||
// Set state
|
||||
@@ -637,8 +646,8 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server binded and listening [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( Handle->FD, true, false, this );
|
||||
if (Selector) {
|
||||
Selector->Add( Handle->FD, true, false, this );
|
||||
}
|
||||
|
||||
// Set state
|
||||
@@ -711,8 +720,8 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server accepted Remote TCP Client connection [%s]", Name, Handle->Name, ClientAddress );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( (*RemoteClient)->FD, true, true, this );
|
||||
if (Selector) {
|
||||
Selector->Add( (*RemoteClient)->FD, true, true, this );
|
||||
}
|
||||
|
||||
return (*RemoteClient)->FD;
|
||||
@@ -802,8 +811,8 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client connected [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( Handle->FD, true, true, this );
|
||||
if (Selector) {
|
||||
Selector->Add( Handle->FD, true, true, this );
|
||||
}
|
||||
|
||||
// Set status
|
||||
@@ -816,8 +825,8 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client waiting to connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( Handle->FD, true, true, this );
|
||||
if (Selector) {
|
||||
Selector->Add( Handle->FD, true, true, this );
|
||||
}
|
||||
|
||||
// Set status
|
||||
@@ -830,8 +839,8 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client could not connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Remove from Select List
|
||||
if (Select) {
|
||||
Select->Remove( Handle->FD, true, true );
|
||||
if (Selector) {
|
||||
Selector->Remove( Handle->FD, true, true );
|
||||
}
|
||||
|
||||
// Close socket
|
||||
@@ -950,8 +959,8 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
||||
};
|
||||
|
||||
// Remove from Select List
|
||||
if (!Fail && Select) {
|
||||
Select->Remove( Handle->FD, true, true );
|
||||
if (!Fail && Selector) {
|
||||
Selector->Remove( Handle->FD, true, true );
|
||||
}
|
||||
|
||||
// Reset FD
|
||||
@@ -982,8 +991,8 @@ bool CSelectableCore::Read( THandle * Handle )
|
||||
ClientFD = OpenRemoteClientSocket( Handle );
|
||||
if (ClientFD != -1) {
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( ClientFD, true, true, this );
|
||||
if (Selector) {
|
||||
Selector->Add( ClientFD, true, true, this );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1061,8 +1070,8 @@ bool CSelectableCore::Write( THandle * Handle )
|
||||
}
|
||||
|
||||
// Remove from set for select write
|
||||
if (Select) {
|
||||
Select->Remove( Handle->FD, false, true );
|
||||
if (Selector) {
|
||||
Selector->Remove( Handle->FD, false, true );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1086,16 +1095,16 @@ bool CSelectableCore::Write( THandle * Handle )
|
||||
// Check if Buffer emtpy
|
||||
if (!Handle->OutBuffer->Len()) {
|
||||
// Add to Select Write list
|
||||
if (Select) {
|
||||
Select->Remove( Handle->FD, false, true );
|
||||
if (Selector) {
|
||||
Selector->Remove( Handle->FD, false, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Output buffer to write from, so remove from Write list
|
||||
if (Select) {
|
||||
Select->Remove( Handle->FD, false, true );
|
||||
if (Selector) {
|
||||
Selector->Remove( Handle->FD, false, true );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -1267,8 +1276,8 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
||||
BytesWritten = ChildHandle->OutBuffer->Push( true, Data, Len );
|
||||
|
||||
// Add to select write list
|
||||
if (BytesWritten) {
|
||||
Select->Add( ChildHandle->FD, false, true, this );
|
||||
if (BytesWritten && Selector) {
|
||||
Selector->Add( ChildHandle->FD, false, true, this );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1296,8 +1305,8 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
||||
BytesWritten = Handle->OutBuffer->Push( true, Data, Len );
|
||||
|
||||
// Add to select write list
|
||||
if (BytesWritten) {
|
||||
Select->Add( Handle->FD, false, true, this );
|
||||
if (BytesWritten && Selector) {
|
||||
Selector->Add( Handle->FD, false, true, this );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -138,7 +138,7 @@ protected:
|
||||
|
||||
public:
|
||||
// Life Cycle
|
||||
CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pLogLevel );
|
||||
CSelect( long SelectTimeout, EDebugLevel pLogLevel );
|
||||
~CSelect();
|
||||
|
||||
// Parameters
|
||||
@@ -163,7 +163,7 @@ protected:
|
||||
THandle * FirstHandle;
|
||||
|
||||
// Select interface
|
||||
CSelect * Select;
|
||||
CSelect * Selector;
|
||||
|
||||
// Configuration
|
||||
virtual bool LoadConfigData();
|
||||
@@ -210,7 +210,7 @@ protected:
|
||||
|
||||
public:
|
||||
// Life Cycle
|
||||
CSelectableCore( const char * Name, CSelect * pSelect, CLogCore * pLog );
|
||||
CSelectableCore( const char * Name, const char * pType = "Selectable" );
|
||||
virtual ~CSelectableCore();
|
||||
|
||||
// Finding Handles
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "SignalCore.h"
|
||||
#include "LogCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
@@ -20,8 +20,8 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Global vars
|
||||
extern CLogCore * Log;
|
||||
extern char * ProcessName;
|
||||
extern char * ProcessName;
|
||||
extern CApplication * Application;
|
||||
|
||||
// Termination Vars
|
||||
bool Terminate = false;
|
||||
@@ -85,15 +85,15 @@ void SignalTerminate( int sig )
|
||||
|
||||
std::cerr << std::endl << ProcessName << ": ***********************************" << std::endl;
|
||||
|
||||
// Create Log Entry
|
||||
if (Log)
|
||||
// Create Application->Log Entry
|
||||
if (Application->Log)
|
||||
{
|
||||
Log->Message( dlLow, dlLow, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount );
|
||||
Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount );
|
||||
// Check for Terminate Limit
|
||||
if (TermCount < MaxTermCount) {
|
||||
Log->Message( dlLow, dlLow, "%s: ** Terminating normally... **", ProcessName );
|
||||
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating normally... **", ProcessName );
|
||||
} else {
|
||||
Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
||||
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -136,10 +136,10 @@ void SignalAbort( int sig )
|
||||
// Show signal received
|
||||
std::cerr << std::endl << ProcessName << ": ********************************" << std::endl;
|
||||
|
||||
// Create Log Entry - but don't post
|
||||
if (Log) {
|
||||
Log->Message( dlLow, dlLow, "%s: ** %s signal received **", ProcessName, SigName );
|
||||
Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
||||
// Create Application->Log Entry - but don't post
|
||||
if (Application->Log) {
|
||||
Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received **", ProcessName, SigName );
|
||||
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
||||
}
|
||||
else {
|
||||
std::cerr << ProcessName << ": ** " << SigName << " signal received **" << std::endl;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
*/
|
||||
|
||||
// redA Libraries
|
||||
#include "ApplicationCore.h"
|
||||
#include "WatchdogCore.h"
|
||||
#include "TimingCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
@@ -19,12 +19,13 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Global vars
|
||||
extern char * ProcessName;
|
||||
extern char * ProcessName;
|
||||
//extern CApplication * Application;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CWatchdogCore::CWatchdogCore( const char * pName, CSelect * pSelect, CLogCore * pLog ) :
|
||||
CSelectableCore( pName, pSelect, pLog )
|
||||
CWatchdogCore::CWatchdogCore( const char * pName ) :
|
||||
CSelectableCore( pName, "WatchdogClient" )
|
||||
{
|
||||
// Create protocol
|
||||
Protocol = new CLiteProtocol( 50, '\x01', '\x02', '\x00' );
|
||||
@@ -34,8 +35,8 @@ CWatchdogCore::CWatchdogCore( const char * pName, CSelect * pSelect, CLogCore *
|
||||
PingInterval = 500;
|
||||
SetStartTime( &PingTimer );
|
||||
|
||||
// Create handle
|
||||
Ping = CreateHandle( "Ping", true );
|
||||
// Handle
|
||||
Ping = NULL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -47,6 +48,18 @@ CWatchdogCore::~CWatchdogCore()
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CWatchdogCore::LoadConfigData()
|
||||
{
|
||||
// Call Previous load config
|
||||
CSelectableCore::LoadConfigData();
|
||||
|
||||
// Set Auto Mange
|
||||
SetInterval( DataTree->GetInt( ConfigMember, "Parameters/PingInterval", 500, true ));
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CWatchdogCore::SetInterval( int pPingInterval )
|
||||
{
|
||||
PingInterval = pPingInterval;
|
||||
@@ -54,6 +67,17 @@ bool CWatchdogCore::SetInterval( int pPingInterval )
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CWatchdogCore::Init()
|
||||
{
|
||||
// Create handle and set reference, if not done
|
||||
if (!(Ping = GetHandle( "Ping" )))
|
||||
Ping = CreateHandle( "Ping", false );
|
||||
|
||||
// Previous init
|
||||
return CSelectableCore::Init();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CWatchdogCore::Process()
|
||||
{
|
||||
if (Timeout( PingTimer, PingInterval ))
|
||||
|
||||
@@ -32,14 +32,20 @@ private:
|
||||
|
||||
public:
|
||||
// Life Cycle
|
||||
CWatchdogCore( const char * pName, CSelect * pSelect, CLogCore * pLog );
|
||||
CWatchdogCore( const char * pName );
|
||||
virtual ~CWatchdogCore();
|
||||
|
||||
// Configuration
|
||||
// Load Configuration
|
||||
virtual bool LoadConfigData();
|
||||
|
||||
// Manually set Configuration
|
||||
bool SetInterval( int pPingInterval );
|
||||
|
||||
// Initialisation
|
||||
virtual bool Init();
|
||||
|
||||
// Process
|
||||
virtual bool Process();
|
||||
virtual bool Process();
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user