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)
|
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 * CDataTree::GetIndexChild( TDataMember * Parent, const int Index )
|
||||||
{
|
{
|
||||||
TDataMember * Child;
|
TDataMember * Child;
|
||||||
@@ -302,7 +280,7 @@ TDataMember * CDataTree::GetIndexChild( TDataMember * Parent, const int Index )
|
|||||||
|
|
||||||
// Get Parent
|
// Get Parent
|
||||||
if (!Parent)
|
if (!Parent)
|
||||||
Parent = RootMember;
|
return NULL;
|
||||||
|
|
||||||
// Get Indexed child
|
// Get Indexed child
|
||||||
Count = 0;
|
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 )
|
bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
|
||||||
{
|
{
|
||||||
TDataMember * Parent;
|
TDataMember * Parent;
|
||||||
@@ -357,7 +349,7 @@ bool CDataTree::DeleteAll()
|
|||||||
bool CDataTree::SetValuePtr( TDataMember * Member, EDataType Type, char * Value, int Len )
|
bool CDataTree::SetValuePtr( TDataMember * Member, EDataType Type, char * Value, int Len )
|
||||||
{
|
{
|
||||||
// Clear previous value
|
// Clear previous value
|
||||||
if (Member->Value != NULL) {
|
if (Member->Value != NULL || (Member->FirstChild != NULL)) {
|
||||||
DestroyValue( Member );
|
DestroyValue( Member );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,9 +68,11 @@ public:
|
|||||||
EDataType GetType( TDataMember * BaseMember, const char * Path );
|
EDataType GetType( TDataMember * BaseMember, const char * Path );
|
||||||
TDataMember * GetMember( TDataMember * BaseMember, const char * Path, bool Create = false );
|
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, const char * Default = NULL, bool Create = false );
|
||||||
const char * GetStr( TDataMember * BaseMember, const char * Path, int &Len, 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>
|
#include <unistd.h>
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "DeviceCore.h"
|
#include "DeviceCore.h"
|
||||||
#include "FunctionCore.h"
|
|
||||||
#include "TimingCore.h"
|
|
||||||
#include "LogCore.h"
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CDeviceCore::CDeviceCore( const char * pName, CLogCore * pLog ) :
|
// Global Vars
|
||||||
CFunctionCore( pName, pLog )
|
//extern char * ProcessName;
|
||||||
|
//extern CApplication * Application;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CDeviceCore::CDeviceCore( const char * pName, const char * pType ) :
|
||||||
|
CFunctionCore( pName, pType )
|
||||||
{
|
{
|
||||||
// Clear Parameters
|
// Clear Parameters
|
||||||
FirstDevice = NULL;
|
FirstDevice = NULL;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "FunctionCore.h"
|
#include "FunctionCore.h"
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
/* no additional */
|
/* none */
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Life cycle
|
// Life cycle
|
||||||
CDeviceCore( const char * pName, CLogCore * pLog );
|
CDeviceCore( const char * pName, const char * Type = "Device" );
|
||||||
virtual ~CDeviceCore();
|
virtual ~CDeviceCore();
|
||||||
|
|
||||||
// Generate events
|
// Generate events
|
||||||
|
|||||||
13
FileCore.cpp
13
FileCore.cpp
@@ -6,10 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "FileCore.h"
|
#include "FileCore.h"
|
||||||
#include "FunctionCore.h"
|
|
||||||
#include "TimingCore.h"
|
|
||||||
#include "LogCore.h"
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -22,13 +20,14 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Constants
|
// Global Vars
|
||||||
const float PI = 3.1415927;
|
//extern char * ProcessName;
|
||||||
|
//extern CApplication * Application;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CFileCore::CFileCore( const char * pName, CLogCore * pLog ) :
|
CFileCore::CFileCore( const char * pName, const char * pType ) :
|
||||||
CFunctionCore( pName, pLog )
|
CFunctionCore( pName, pType )
|
||||||
{
|
{
|
||||||
FirstFile = NULL;
|
FirstFile = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Life cycle
|
// Life cycle
|
||||||
CFileCore( const char * pName, CLogCore * pLog );
|
CFileCore( const char * pName, const char * pType = "File" );
|
||||||
virtual ~CFileCore();
|
virtual ~CFileCore();
|
||||||
|
|
||||||
// Manage files
|
// Manage files
|
||||||
|
|||||||
226
FunctionCore.cpp
226
FunctionCore.cpp
@@ -6,9 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "FunctionCore.h"
|
#include "FunctionCore.h"
|
||||||
#include "TimingCore.h"
|
|
||||||
#include "LogCore.h"
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -17,12 +16,14 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Global Vars
|
||||||
extern char * ProcessName;
|
extern char * ProcessName;
|
||||||
|
extern CApplication * Application;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Life cycle
|
// Life cycle
|
||||||
CFunctionCore::CFunctionCore( const char * pName, CLogCore * pLog )
|
CFunctionCore::CFunctionCore( const char * pName, const char * pType )
|
||||||
{
|
{
|
||||||
// Set name
|
// Set name
|
||||||
if (pName) {
|
if (pName) {
|
||||||
@@ -33,15 +34,28 @@ CFunctionCore::CFunctionCore( const char * pName, CLogCore * pLog )
|
|||||||
Name = NULL;
|
Name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data Tree
|
// Set Type
|
||||||
DataTree = NULL;
|
if (pType) {
|
||||||
BaseMember = NULL;
|
Type = (char*)malloc( strlen(pType)+1 );
|
||||||
|
strcpy( Type, pType );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Type = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Channels
|
// Channels
|
||||||
FirstChannel = NULL;
|
FirstChannel = NULL;
|
||||||
|
|
||||||
|
// List
|
||||||
|
Application->AddFunction( this );
|
||||||
|
|
||||||
|
// Data Tree
|
||||||
|
DataTree = Application->DataTree;
|
||||||
|
ConfigMember = NULL;
|
||||||
|
LinkConfigMember = NULL;
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
Log = pLog;
|
Log = Application->Log;
|
||||||
LogLevel = dlNone;
|
LogLevel = dlNone;
|
||||||
LogOutput = OUT_NORMAL;
|
LogOutput = OUT_NORMAL;
|
||||||
}
|
}
|
||||||
@@ -90,75 +104,50 @@ CFunctionCore::~CFunctionCore()
|
|||||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Destroyed", ProcessName, Name );
|
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Destroyed", ProcessName, Name );
|
||||||
|
|
||||||
// Destroy Name
|
// Destroy Name
|
||||||
if (Name) {
|
if (Name) free( Name );
|
||||||
free( Name );
|
if (Type) free( Type );
|
||||||
}
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CFunctionCore::LoadConfigData()
|
bool CFunctionCore::LoadConfigData()
|
||||||
{
|
{
|
||||||
TDataMember * TempMember;
|
TDataMember * TempMember;
|
||||||
|
EDebugLevel pLogLevel;
|
||||||
|
int pLogOutput;
|
||||||
char * TempStr;
|
char * TempStr;
|
||||||
|
|
||||||
// Get debug level
|
// Get debug level
|
||||||
LogLevel = dlNone;
|
pLogLevel = dlNone;
|
||||||
TempStr = (char*)DataTree->GetStr( BaseMember, "Log/Level", "Medium", true );
|
TempStr = (char*)DataTree->GetStr( ConfigMember, "Log/Level", "Medium", true );
|
||||||
if (TempStr)
|
if (TempStr)
|
||||||
{
|
{
|
||||||
if (!strcasecmp( TempStr, "Low" ))
|
if (!strcasecmp( TempStr, "Low" ))
|
||||||
LogLevel = dlLow;
|
pLogLevel = dlLow;
|
||||||
else if (!strcasecmp( TempStr, "Medium" ))
|
else if (!strcasecmp( TempStr, "Medium" ))
|
||||||
LogLevel = dlMedium;
|
pLogLevel = dlMedium;
|
||||||
else if (!strcasecmp( TempStr, "High" ))
|
else if (!strcasecmp( TempStr, "High" ))
|
||||||
LogLevel = dlHigh;
|
pLogLevel = dlHigh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set debug output
|
// Set debug output
|
||||||
LogOutput = 0;
|
pLogOutput = 0;
|
||||||
TempMember = DataTree->GetMember( BaseMember, "Log/Output[0]", true );
|
TempMember = DataTree->GetFirstChild( ConfigMember, "Log/Output", true );
|
||||||
while (TempMember)
|
while (TempMember)
|
||||||
{
|
{
|
||||||
if (TempMember->Value)
|
if (TempMember->Value)
|
||||||
{
|
{
|
||||||
if (!strcasecmp( TempMember->Value, "Normal"))
|
if (!strcasecmp( TempMember->Value, "Normal"))
|
||||||
LogOutput |= OUT_NORMAL;
|
pLogOutput |= OUT_NORMAL;
|
||||||
else if (!strcasecmp( TempMember->Value, "Bin"))
|
else if (!strcasecmp( TempMember->Value, "Bin"))
|
||||||
LogOutput |= OUT_BIN;
|
pLogOutput |= OUT_BIN;
|
||||||
else if (!strcasecmp( TempMember->Value, "Hex"))
|
else if (!strcasecmp( TempMember->Value, "Hex"))
|
||||||
LogOutput |= OUT_HEX;
|
pLogOutput |= OUT_HEX;
|
||||||
else if (!strcasecmp( TempMember->Value, "Count"))
|
else if (!strcasecmp( TempMember->Value, "Count"))
|
||||||
LogOutput |= OUT_COUNT;
|
pLogOutput |= OUT_COUNT;
|
||||||
else if (!strcasecmp( TempMember->Value, "AsIs"))
|
else if (!strcasecmp( TempMember->Value, "AsIs"))
|
||||||
LogOutput |= OUT_ASIS;
|
pLogOutput |= OUT_ASIS;
|
||||||
else if (!strcasecmp( TempMember->Value, "CRLF"))
|
else if (!strcasecmp( TempMember->Value, "CRLF"))
|
||||||
LogOutput |= OUT_CRLF;
|
pLogOutput |= OUT_CRLF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next
|
// Next
|
||||||
@@ -166,15 +155,17 @@ bool CFunctionCore::LoadConfigData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set Logging
|
// Set Logging
|
||||||
InitLogging( LogLevel, LogOutput );
|
SetLogParam( pLogLevel, pLogOutput );
|
||||||
|
|
||||||
// Set debug output
|
// Load Channels
|
||||||
TempMember = DataTree->GetFirstChild( DataTree->GetMember( BaseMember, "Channels" ) );
|
TempMember = DataTree->GetFirstChild( ConfigMember, "Channels", true );
|
||||||
while (TempMember)
|
while (TempMember)
|
||||||
{
|
{
|
||||||
AddChannel( DataTree->GetStr( TempMember, "Name" ),
|
if (TempMember->Name) {
|
||||||
|
AddChannel( TempMember->Name,
|
||||||
DataTree->GetBool( TempMember, "InputEnabled", true, true ),
|
DataTree->GetBool( TempMember, "InputEnabled", true, true ),
|
||||||
DataTree->GetBool( TempMember, "OutputEnabled", false, true ));
|
DataTree->GetBool( TempMember, "OutputEnabled", false, true ));
|
||||||
|
}
|
||||||
|
|
||||||
// Next
|
// Next
|
||||||
TempMember = DataTree->GetNextChild( TempMember );
|
TempMember = DataTree->GetNextChild( TempMember );
|
||||||
@@ -184,20 +175,112 @@ bool CFunctionCore::LoadConfigData()
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CFunctionCore::InitLogging( EDebugLevel pDebugLevel, int pOutputDisplay )
|
bool CFunctionCore::LoadChannelLinkData()
|
||||||
{
|
{
|
||||||
// Output
|
TChannel * Channel;
|
||||||
LogLevel = pDebugLevel;
|
TDataMember * ChannelMember;
|
||||||
LogOutput = pOutputDisplay;
|
TDataMember * FunctionMember;
|
||||||
|
|
||||||
// Report status
|
// Process each Channel
|
||||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Created", ProcessName, Name );
|
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;
|
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;
|
LogLevel = pDebugLevel;
|
||||||
return true;
|
return true;
|
||||||
@@ -242,13 +325,14 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Automated Data Input/Output
|
// 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;
|
TChannel * Channel = NULL;
|
||||||
TChannelLink ** LinkedChannel = NULL;
|
TChannelLink ** LinkedChannel = NULL;
|
||||||
|
|
||||||
// Get Channel
|
// Get Channel
|
||||||
if (!OutFunction || !OutFunction || !(Channel = GetChannel( ChannelName ))) {
|
if (!(OutFunction = Application->GetFunction( OutFunctionName )) || !(Channel = GetChannel( ChannelName ))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,25 +360,29 @@ bool CFunctionCore::LinkInputChannel( const char * ChannelName, CFunctionCore *
|
|||||||
|
|
||||||
// Link Return direction as well
|
// Link Return direction as well
|
||||||
if (Bidirectional) {
|
if (Bidirectional) {
|
||||||
return OutFunction->LinkInputChannel( OutChannelName, this, ChannelName, false );
|
return OutFunction->LinkInputChannel( OutChannelName, Name, ChannelName, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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;
|
TChannelLink ** LinkedChannel = NULL;
|
||||||
|
|
||||||
// Get Channel
|
// Check if Channels & Function exist
|
||||||
if (!InFunction || !InChannelName || !(Channel = GetChannel( ChannelName ))) {
|
if (!(OutChannel = GetChannel( ChannelName )) ||
|
||||||
|
!(InFunction = Application->GetFunction( InFunctionName )) ||
|
||||||
|
!(InChannel = InFunction->GetChannel( InChannelName )) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if linked Channel exists
|
// Check if linked Channel exists
|
||||||
LinkedChannel = &(Channel->FirstOutput);
|
LinkedChannel = &(OutChannel->FirstOutput);
|
||||||
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, InChannelName ) )) {
|
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, InChannelName ) )) {
|
||||||
LinkedChannel = &((*LinkedChannel)->Next);
|
LinkedChannel = &((*LinkedChannel)->Next);
|
||||||
}
|
}
|
||||||
@@ -317,7 +405,7 @@ bool CFunctionCore::LinkOutputChannel( const char * ChannelName, CFunctionCore *
|
|||||||
|
|
||||||
// Link return direction as well
|
// Link return direction as well
|
||||||
if (Bidirectional) {
|
if (Bidirectional) {
|
||||||
return InFunction->LinkOutputChannel( InChannelName, this, ChannelName, false );
|
return InFunction->LinkOutputChannel( InChannelName, Name, ChannelName, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -55,10 +55,12 @@ class CFunctionCore
|
|||||||
protected:
|
protected:
|
||||||
// Function Definition
|
// Function Definition
|
||||||
char * Name;
|
char * Name;
|
||||||
|
char * Type;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
CDataTree * DataTree;
|
CDataTree * DataTree;
|
||||||
TDataMember * BaseMember;
|
TDataMember * ConfigMember;
|
||||||
|
TDataMember * LinkConfigMember;
|
||||||
|
|
||||||
// Channels
|
// Channels
|
||||||
TChannel * FirstChannel;
|
TChannel * FirstChannel;
|
||||||
@@ -77,27 +79,34 @@ protected:
|
|||||||
return Channel;
|
return Channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load configuraiton
|
// Load configuration
|
||||||
virtual bool LoadConfigData();
|
virtual bool LoadConfigData();
|
||||||
|
virtual bool LoadChannelLinkData();
|
||||||
|
|
||||||
// Manual Data Input/Output
|
// Manual Data Input/Output
|
||||||
virtual int Output( const TChannel * Channel, const char * Data, int Len );
|
virtual int Output( const TChannel * Channel, const char * Data, int Len );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Life cycle
|
// Life cycle
|
||||||
CFunctionCore( const char * pName, CLogCore * pLog );
|
CFunctionCore( const char * pName, const char * Type );
|
||||||
virtual ~CFunctionCore();
|
virtual ~CFunctionCore();
|
||||||
|
|
||||||
// Load Configuration
|
// Load Configuration
|
||||||
virtual bool LoadConfig( CDataTree * pDataTree, const char * pBasePath );
|
virtual bool Init();
|
||||||
virtual bool LoadConfig( CDataTree * pDataTree, TDataMember * pBaseMember );
|
|
||||||
|
bool InitConfig( const char * pConfigPath );
|
||||||
|
bool InitConfig( TDataMember * pConfigMember );
|
||||||
|
|
||||||
|
bool InitChannelLinks( const char * pLinkConfigPath );
|
||||||
|
bool InitChannelLinks( TDataMember *pLinkConfigMember );
|
||||||
|
|
||||||
// Set Parameters Manually
|
// Set Parameters Manually
|
||||||
bool InitLogging( EDebugLevel pDebugLevel, int pOutputDisplay );
|
bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay );
|
||||||
bool SetDebugLevel( EDebugLevel pDebugLevel );
|
bool SetLogLevel( EDebugLevel pDebugLevel );
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
inline const char * GetName() { return Name; };
|
inline const char * GetName() { return Name; };
|
||||||
|
inline const char * GetType() { return Type; };
|
||||||
|
|
||||||
// Manage Channels
|
// Manage Channels
|
||||||
virtual TChannel * AddChannel( const char * ChannelName, const bool pInputEnable = true, const bool pOutputEnabled = true );
|
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 );
|
virtual int Output( const char * ChannelName, const char * Data, int Len = -1 );
|
||||||
|
|
||||||
// Automated Data Input/Output
|
// Automated Data Input/Output
|
||||||
virtual bool LinkInputChannel( const char * ChannelName, CFunctionCore * OutFunction, const char * OutChannelName, bool Bidirectional );
|
virtual bool LinkInputChannel( const char * ChannelName, const char * OutFunctionName, const char * OutChannelName, bool Bidirectional );
|
||||||
virtual bool LinkOutputChannel( const char * ChannelName, CFunctionCore * InFunction, const char * InChannelName, bool Bidirectional );
|
virtual bool LinkOutputChannel( const char * ChannelName, const char * InFunctionName, const char * InChannelName, bool Bidirectional );
|
||||||
virtual bool Process() = 0;
|
virtual bool Process() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "SelectableCore.h"
|
#include "SelectableCore.h"
|
||||||
#include "TimingCore.h"
|
|
||||||
#include "LogCore.h"
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -18,12 +17,14 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Global Vars
|
||||||
extern char * ProcessName;
|
extern char * ProcessName;
|
||||||
|
extern CApplication * Application;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Create Select
|
// Create Select
|
||||||
CSelect::CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pDebugLevel )
|
CSelect::CSelect( long SelectTimeout, EDebugLevel pDebugLevel )
|
||||||
{
|
{
|
||||||
// Clear List
|
// Clear List
|
||||||
FirstHandle = NULL;
|
FirstHandle = NULL;
|
||||||
@@ -39,11 +40,11 @@ CSelect::CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pDebugLevel )
|
|||||||
SetInterval( &Timeout, SelectTimeout );
|
SetInterval( &Timeout, SelectTimeout );
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
Log = pLog;
|
Log = Application->Log;
|
||||||
LogLevel = pDebugLevel;
|
LogLevel = pDebugLevel;
|
||||||
|
|
||||||
// Show status
|
// 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
|
// Show status
|
||||||
if (Log) Log->Message( LogLevel, dlLow, "%s: Select - Destroyed", ProcessName );
|
if (Log) Log->Message( LogLevel, dlLow, "%s: Selector - Destroyed", ProcessName );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -113,7 +114,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
|||||||
FD_SET( FD, &ReadTestFDS );
|
FD_SET( FD, &ReadTestFDS );
|
||||||
|
|
||||||
// Log event
|
// 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
|
// Add Write Select
|
||||||
@@ -122,7 +123,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
|||||||
FD_SET( FD, &WriteTestFDS );
|
FD_SET( FD, &WriteTestFDS );
|
||||||
|
|
||||||
// Log event
|
// 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
|
// Check Maximum File Handle
|
||||||
@@ -150,7 +151,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
|
|||||||
FD_CLR( FD, &ReadTestFDS);
|
FD_CLR( FD, &ReadTestFDS);
|
||||||
|
|
||||||
// Log event
|
// 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
|
// Remove from set for select write check
|
||||||
@@ -159,7 +160,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
|
|||||||
FD_CLR( FD, &WriteTestFDS);
|
FD_CLR( FD, &WriteTestFDS);
|
||||||
|
|
||||||
// Log event
|
// 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
|
// 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 );
|
Events = select( MaxFD, &ReadFDS, &WriteFDS, (fd_set*)NULL, &STimeout );
|
||||||
if (Events < 0)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "SelectableCore.h"
|
#include "SelectableCore.h"
|
||||||
#include "TimingCore.h"
|
|
||||||
#include "LogCore.h"
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -30,14 +29,20 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CSelectableCore::CSelectableCore( const char * pName, CSelect * pSelect, CLogCore * pLog ) :
|
// Global Vars
|
||||||
CFunctionCore( pName, pLog )
|
//extern char * ProcessName;
|
||||||
|
extern CApplication * Application;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CSelectableCore::CSelectableCore( const char * pName, const char * pType ) :
|
||||||
|
CFunctionCore( pName, pType )
|
||||||
{
|
{
|
||||||
|
// Quick access
|
||||||
|
Selector = Application->Selector;
|
||||||
|
|
||||||
// Handles
|
// Handles
|
||||||
FirstHandle = NULL;
|
FirstHandle = NULL;
|
||||||
|
|
||||||
// Select
|
|
||||||
Select = pSelect;
|
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -73,13 +78,17 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
// Call Previous load config
|
// Call Previous load config
|
||||||
CFunctionCore::LoadConfigData();
|
CFunctionCore::LoadConfigData();
|
||||||
|
|
||||||
// Set debug output
|
// Load Handles
|
||||||
TempMember = DataTree->GetFirstChild( DataTree->GetMember( BaseMember, "Handles", true ) );
|
TempMember = DataTree->GetFirstChild( DataTree->GetMember( ConfigMember, "Handles", true ) );
|
||||||
while (TempMember)
|
while (TempMember)
|
||||||
{
|
{
|
||||||
|
// Check if name is valid
|
||||||
|
if (!TempMember->Name || !*TempMember->Name)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Create Handle and channel link
|
// Create Handle and channel link
|
||||||
Handle = CreateHandle( DataTree->GetStr( TempMember, "Name" ), false );
|
Handle = CreateHandle( TempMember->Name, false );
|
||||||
Handle->Channel = GetChannel( DataTree->GetStr( TempMember, "Name" ) );
|
Handle->Channel = GetChannel( DataTree->GetStr( TempMember, "Channel" ) );
|
||||||
|
|
||||||
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
||||||
if (!strcasecmp( Type, "Port" ))
|
if (!strcasecmp( Type, "Port" ))
|
||||||
@@ -94,7 +103,7 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
else if (!strcasecmp( Type, "TCPserver" ))
|
else if (!strcasecmp( Type, "TCPserver" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
|
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 ))) {
|
if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
sprintf( Path, "Address/%s/Address", Name );
|
||||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
|
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
|
||||||
@@ -106,7 +115,7 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
else if (!strcasecmp( Type, "TCPclient" ))
|
else if (!strcasecmp( Type, "TCPclient" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
|
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 ))) {
|
if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
sprintf( Path, "Address/%s/Address", Name );
|
||||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
|
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 );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port opened [%s]", Name, Handle->Name, Handle->Path );
|
||||||
|
|
||||||
// Add to Select Lists
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( Handle->FD, true, false, this );
|
Selector->Add( Handle->FD, true, false, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set state
|
// Set state
|
||||||
@@ -527,8 +536,8 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add to Select Lists
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( Handle->FD, false, true, this );
|
Selector->Add( Handle->FD, false, true, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set state
|
// 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 );
|
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
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( Handle->FD, true, false, this );
|
Selector->Add( Handle->FD, true, false, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set state
|
// 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 );
|
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
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( (*RemoteClient)->FD, true, true, this );
|
Selector->Add( (*RemoteClient)->FD, true, true, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*RemoteClient)->FD;
|
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 );
|
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
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( Handle->FD, true, true, this );
|
Selector->Add( Handle->FD, true, true, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set status
|
// 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) );
|
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
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( Handle->FD, true, true, this );
|
Selector->Add( Handle->FD, true, true, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set status
|
// 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) );
|
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
|
// Remove from Select List
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Remove( Handle->FD, true, true );
|
Selector->Remove( Handle->FD, true, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close socket
|
// Close socket
|
||||||
@@ -950,8 +959,8 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Remove from Select List
|
// Remove from Select List
|
||||||
if (!Fail && Select) {
|
if (!Fail && Selector) {
|
||||||
Select->Remove( Handle->FD, true, true );
|
Selector->Remove( Handle->FD, true, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset FD
|
// Reset FD
|
||||||
@@ -982,8 +991,8 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
ClientFD = OpenRemoteClientSocket( Handle );
|
ClientFD = OpenRemoteClientSocket( Handle );
|
||||||
if (ClientFD != -1) {
|
if (ClientFD != -1) {
|
||||||
// Add to Select Lists
|
// Add to Select Lists
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Add( ClientFD, true, true, this );
|
Selector->Add( ClientFD, true, true, this );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1061,8 +1070,8 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove from set for select write
|
// Remove from set for select write
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Remove( Handle->FD, false, true );
|
Selector->Remove( Handle->FD, false, true );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1086,16 +1095,16 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
// Check if Buffer emtpy
|
// Check if Buffer emtpy
|
||||||
if (!Handle->OutBuffer->Len()) {
|
if (!Handle->OutBuffer->Len()) {
|
||||||
// Add to Select Write list
|
// Add to Select Write list
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Remove( Handle->FD, false, true );
|
Selector->Remove( Handle->FD, false, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No Output buffer to write from, so remove from Write list
|
// No Output buffer to write from, so remove from Write list
|
||||||
if (Select) {
|
if (Selector) {
|
||||||
Select->Remove( Handle->FD, false, true );
|
Selector->Remove( Handle->FD, false, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 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 );
|
BytesWritten = ChildHandle->OutBuffer->Push( true, Data, Len );
|
||||||
|
|
||||||
// Add to select write list
|
// Add to select write list
|
||||||
if (BytesWritten) {
|
if (BytesWritten && Selector) {
|
||||||
Select->Add( ChildHandle->FD, false, true, this );
|
Selector->Add( ChildHandle->FD, false, true, this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1296,8 +1305,8 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
|||||||
BytesWritten = Handle->OutBuffer->Push( true, Data, Len );
|
BytesWritten = Handle->OutBuffer->Push( true, Data, Len );
|
||||||
|
|
||||||
// Add to select write list
|
// Add to select write list
|
||||||
if (BytesWritten) {
|
if (BytesWritten && Selector) {
|
||||||
Select->Add( Handle->FD, false, true, this );
|
Selector->Add( Handle->FD, false, true, this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Life Cycle
|
// Life Cycle
|
||||||
CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pLogLevel );
|
CSelect( long SelectTimeout, EDebugLevel pLogLevel );
|
||||||
~CSelect();
|
~CSelect();
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
@@ -163,7 +163,7 @@ protected:
|
|||||||
THandle * FirstHandle;
|
THandle * FirstHandle;
|
||||||
|
|
||||||
// Select interface
|
// Select interface
|
||||||
CSelect * Select;
|
CSelect * Selector;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
virtual bool LoadConfigData();
|
virtual bool LoadConfigData();
|
||||||
@@ -210,7 +210,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Life Cycle
|
// Life Cycle
|
||||||
CSelectableCore( const char * Name, CSelect * pSelect, CLogCore * pLog );
|
CSelectableCore( const char * Name, const char * pType = "Selectable" );
|
||||||
virtual ~CSelectableCore();
|
virtual ~CSelectableCore();
|
||||||
|
|
||||||
// Finding Handles
|
// Finding Handles
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "SignalCore.h"
|
#include "SignalCore.h"
|
||||||
#include "LogCore.h"
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -20,8 +20,8 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Global vars
|
// Global vars
|
||||||
extern CLogCore * Log;
|
|
||||||
extern char * ProcessName;
|
extern char * ProcessName;
|
||||||
|
extern CApplication * Application;
|
||||||
|
|
||||||
// Termination Vars
|
// Termination Vars
|
||||||
bool Terminate = false;
|
bool Terminate = false;
|
||||||
@@ -85,15 +85,15 @@ void SignalTerminate( int sig )
|
|||||||
|
|
||||||
std::cerr << std::endl << ProcessName << ": ***********************************" << std::endl;
|
std::cerr << std::endl << ProcessName << ": ***********************************" << std::endl;
|
||||||
|
|
||||||
// Create Log Entry
|
// Create Application->Log Entry
|
||||||
if (Log)
|
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
|
// Check for Terminate Limit
|
||||||
if (TermCount < MaxTermCount) {
|
if (TermCount < MaxTermCount) {
|
||||||
Log->Message( dlLow, dlLow, "%s: ** Terminating normally... **", ProcessName );
|
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating normally... **", ProcessName );
|
||||||
} else {
|
} else {
|
||||||
Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -136,10 +136,10 @@ void SignalAbort( int sig )
|
|||||||
// Show signal received
|
// Show signal received
|
||||||
std::cerr << std::endl << ProcessName << ": ********************************" << std::endl;
|
std::cerr << std::endl << ProcessName << ": ********************************" << std::endl;
|
||||||
|
|
||||||
// Create Log Entry - but don't post
|
// Create Application->Log Entry - but don't post
|
||||||
if (Log) {
|
if (Application->Log) {
|
||||||
Log->Message( dlLow, dlLow, "%s: ** %s signal received **", ProcessName, SigName );
|
Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received **", ProcessName, SigName );
|
||||||
Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << ProcessName << ": ** " << SigName << " signal received **" << std::endl;
|
std::cerr << ProcessName << ": ** " << SigName << " signal received **" << std::endl;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
|
#include "ApplicationCore.h"
|
||||||
#include "WatchdogCore.h"
|
#include "WatchdogCore.h"
|
||||||
#include "TimingCore.h"
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -20,11 +20,12 @@
|
|||||||
|
|
||||||
// Global vars
|
// Global vars
|
||||||
extern char * ProcessName;
|
extern char * ProcessName;
|
||||||
|
//extern CApplication * Application;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CWatchdogCore::CWatchdogCore( const char * pName, CSelect * pSelect, CLogCore * pLog ) :
|
CWatchdogCore::CWatchdogCore( const char * pName ) :
|
||||||
CSelectableCore( pName, pSelect, pLog )
|
CSelectableCore( pName, "WatchdogClient" )
|
||||||
{
|
{
|
||||||
// Create protocol
|
// Create protocol
|
||||||
Protocol = new CLiteProtocol( 50, '\x01', '\x02', '\x00' );
|
Protocol = new CLiteProtocol( 50, '\x01', '\x02', '\x00' );
|
||||||
@@ -34,8 +35,8 @@ CWatchdogCore::CWatchdogCore( const char * pName, CSelect * pSelect, CLogCore *
|
|||||||
PingInterval = 500;
|
PingInterval = 500;
|
||||||
SetStartTime( &PingTimer );
|
SetStartTime( &PingTimer );
|
||||||
|
|
||||||
// Create handle
|
// Handle
|
||||||
Ping = CreateHandle( "Ping", true );
|
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 )
|
bool CWatchdogCore::SetInterval( int pPingInterval )
|
||||||
{
|
{
|
||||||
PingInterval = 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()
|
bool CWatchdogCore::Process()
|
||||||
{
|
{
|
||||||
if (Timeout( PingTimer, PingInterval ))
|
if (Timeout( PingTimer, PingInterval ))
|
||||||
|
|||||||
@@ -32,12 +32,18 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Life Cycle
|
// Life Cycle
|
||||||
CWatchdogCore( const char * pName, CSelect * pSelect, CLogCore * pLog );
|
CWatchdogCore( const char * pName );
|
||||||
virtual ~CWatchdogCore();
|
virtual ~CWatchdogCore();
|
||||||
|
|
||||||
// Configuration
|
// Load Configuration
|
||||||
|
virtual bool LoadConfigData();
|
||||||
|
|
||||||
|
// Manually set Configuration
|
||||||
bool SetInterval( int pPingInterval );
|
bool SetInterval( int pPingInterval );
|
||||||
|
|
||||||
|
// Initialisation
|
||||||
|
virtual bool Init();
|
||||||
|
|
||||||
// Process
|
// Process
|
||||||
virtual bool Process();
|
virtual bool Process();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user