Major Update:

- Implement consistent Function addition to application
  - Use TYPE_XXX constants to declare function type
  - Use NewXXXX() methods to call constructor correctly
  - Add FunctionType list (with constructor) to Application
  - Create Function by comparison to FunctionType list
- Simplify LoadConfig() and Init() methods for functions
  - Combine methods into Init() method
  - Pass relevant data member to Init() method
  - Remove all CDataMember references on functions
- ApplicationCore:
  - Split ReadParam() method from LoadConfig() method
  - Split main configuration into separate files:
    - config/ - main config file, general application settings
    - definition/ - application definition, e.g. function blocks
  - Definition and Address List files specified in config file
  - Load address file in address/ branch
  - Made DataTree & JSONparser private
  - Made Config, Definition & Address branches public
  - Removed unnecessary branch references
  - Improved event logging
- DataTreeCore:
  - Allow GetChFirstChild & GetChElement to create parent branches
    with correct type, ie. Object/Array
  - Remove unnecessary Create param from GetXxx functions
  - Bug fix: Print empty objects/arrays correct, ie. empty brackets
  - Bug fix: Adding element at specific index
  - Bug fix: Error when get/create string value with "null"
- FunctionCore:
  - Type param now set as constant via constructor
  - Create empty Handles & Channels objects if none in Config
- SelectableCore:
  - Add Queue length parameter to handles for UNIX and TCP sockets
- DeviceCore:
  - Bug fix: missing Process() method
This commit is contained in:
Charl Wentzel
2018-11-24 13:35:23 +02:00
parent 7434334280
commit a972fb9101
15 changed files with 518 additions and 469 deletions

View File

@@ -12,6 +12,7 @@
#include "ApplicationCore.h" #include "ApplicationCore.h"
#include "WatchdogCore.h" #include "WatchdogCore.h"
#include "FileCore.h" #include "FileCore.h"
#include "DeviceCore.h"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -25,11 +26,7 @@ CApplication::CApplication( EDebugLevel pLogLevel )
// Set signal handlers // Set signal handlers
ConfigureSignalHandlers(); ConfigureSignalHandlers();
// Variables used for configuration DefinitionFile = NULL;
ConfigMember = NULL;
FunctionConfigMember = NULL;
LinkConfigMember = NULL;
ConfigFile = NULL; ConfigFile = NULL;
AddressFile = NULL; AddressFile = NULL;
@@ -40,22 +37,32 @@ CApplication::CApplication( EDebugLevel pLogLevel )
// Create Configuration // Create Configuration
DataTree = new CDataMember(); DataTree = new CDataMember();
Config = DataTree->GetChild( "Config", true );
Definition = DataTree->GetChild( "Definition", true );
AddressList = DataTree->GetChild( "AddressList", true );
JSONparser = new CJSONparse( DataTree ); JSONparser = new CJSONparse( DataTree );
// Selector // Selector
Selector = NULL; Selector = NULL;
// List // List
FirstFunctionType = NULL;
FirstFunction = NULL; FirstFunction = NULL;
// Add Core Function Types
//AddFunctionType( TYPE_FUNCTION, NewFunctionCore ); // <-- Can't add virtual function
AddFunctionType( TYPE_SELECTABLE, NewSelectableCore );
AddFunctionType( TYPE_WATCHDOG, NewWatchdogCore );
AddFunctionType( TYPE_FILE, NewFileCore );
//AddFunctionType( TYPE_DEVICE, NewDeviceCore ); // <-- Can't add virtual function
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CApplication::~CApplication() CApplication::~CApplication()
{ {
TFunctionItem * NextFunction; TFunctionItem * NextFunction;
TFunctionType * NextType;
if (FirstFunction)
{
// Destroy functions // Destroy functions
while (FirstFunction) while (FirstFunction)
{ {
@@ -64,6 +71,14 @@ CApplication::~CApplication()
free( FirstFunction ); free( FirstFunction );
FirstFunction = NextFunction; FirstFunction = NextFunction;
} }
// Destroy function types
while (FirstFunctionType)
{
NextType = FirstFunctionType->Next;
free( FirstFunctionType->Name );
free( FirstFunctionType );
FirstFunctionType = NextType;
} }
// Show Completion // Show Completion
@@ -98,7 +113,7 @@ void CApplication::GetProcessName( char ** ProcessName, char * pFilePath )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CApplication::LoadConfig( int argc, char *argv[], const char * pConfigPath ) bool CApplication::ReadParam( int argc, char *argv[] )
{ {
// Read Parameters // Read Parameters
if ((argc != 2)) if ((argc != 2))
@@ -116,16 +131,49 @@ bool CApplication::LoadConfig( int argc, char *argv[], const char * pConfigPath
// Load parameters // Load parameters
GetProcessName( &ProcessName, argv[1] ); GetProcessName( &ProcessName, argv[1] );
ConfigFile = argv[1]; ConfigFile = argv[1];
return true;
} }
}
//---------------------------------------------------------------------------
// Load Application List bool CApplication::LoadConfig()
if (JSONparser->ReadFromFile( pConfigPath, ConfigFile )) { {
if (Log) Log->Message( dlLow, dlLow, "%s: Config file loaded (%s)", ProcessName, ConfigFile ); // Load Configuration Data
} else { if (!JSONparser->ReadFromFile( "Config", ConfigFile )) {
if (Log) Log->Message( dlLow, dlLow, "%s: Fail to load config file (%s)- %s", ProcessName, ConfigFile, JSONparser->GetError() ); if (Log) Log->Message( dlLow, dlLow, "%s: Fail to load Configuration file (%s)- %s", ProcessName, ConfigFile, JSONparser->GetError() );
return false; return false;
} }
//JSONparser->WriteToScreen( pConfigPath, 2 ); else {
//JSONparser->WriteToScreen( "config", 2 );
if (Log) Log->Message( dlLow, dlLow, "%s: Configuration file loaded (%s)", ProcessName, ConfigFile );
}
// Load Application Definition
if (!(DefinitionFile = (char*)Config->GetChStr( "DefinitionFile" ))) {
if (Log) Log->Message( dlLow, dlLow, "%s: No Application Definition file specified", ProcessName );
return false;
}
else if (!JSONparser->ReadFromFile( "Definition", DefinitionFile )) {
if (Log) Log->Message( dlLow, dlLow, "%s: Fail to load Application Definition file (%s)- %s", ProcessName, DefinitionFile, JSONparser->GetError() );
return false;
}
else {
//JSONparser->WriteToScreen( "application", 2 );
if (Log) Log->Message( dlLow, dlLow, "%s: Application Definition file loaded (%s)", ProcessName, DefinitionFile );
}
// Load Address List
if (!(AddressFile = (char*)Config->GetChStr( "AddressFile" ))) {
if (Log) Log->Message( dlLow, dlLow, "%s: No Address List file specified", ProcessName );
}
else if (!JSONparser->ReadFromFile( "AddressList", AddressFile )) {
if (Log) Log->Message( dlLow, dlLow, "%s: Fail to load Address List file (%s)- %s", ProcessName, AddressFile, JSONparser->GetError() );
return false;
}
else {
//JSONparser->WriteToScreen( "address", 2 );
if (Log) Log->Message( dlLow, dlLow, "%s: Address List file loaded (%s)", ProcessName, AddressFile );
}
// Loaded successfully // Loaded successfully
return true; return true;
@@ -136,79 +184,11 @@ bool CApplication::SaveConfig()
{ {
// Save updated configuration // Save updated configuration
if (ConfigFile && *ConfigFile) if (ConfigFile && *ConfigFile)
JSONparser->WriteToFile( "config", ConfigFile ); JSONparser->WriteToFile( "Config", ConfigFile );
if (DefinitionFile && *DefinitionFile)
JSONparser->WriteToFile( "Definition", DefinitionFile );
if (AddressFile && *AddressFile ) if (AddressFile && *AddressFile )
JSONparser->WriteToFile( "address", AddressFile ); JSONparser->WriteToFile( "AddressList", AddressFile );
return true;
}
//---------------------------------------------------------------------------
bool CApplication::LoadConfigData()
{
CDataMember * TempMember;
EDebugLevel pLogLevel;
int pLogOutput;
char * TempStr;
// Get debug level
pLogLevel = dlNone;
TempStr = (char*)ConfigMember->GetChStr( "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;
if ((TempMember = ConfigMember->GetChild( "Log/Output", true )))
{
TempMember = TempMember->GetFirstChild();
while (TempMember)
{
if ((TempStr = (char*)TempMember->GetStr()))
{
if (!strcasecmp( TempStr, "Normal"))
pLogOutput |= OUT_NORMAL;
else if (!strcasecmp( TempStr, "Bin"))
pLogOutput |= OUT_BIN;
else if (!strcasecmp( TempStr, "Hex"))
pLogOutput |= OUT_HEX;
else if (!strcasecmp( TempStr, "Count"))
pLogOutput |= OUT_COUNT;
else if (!strcasecmp( TempStr, "AsIs"))
pLogOutput |= OUT_ASIS;
else if (!strcasecmp( TempStr, "CRLF"))
pLogOutput |= OUT_CRLF;
}
// Next
TempMember = TempMember->GetNextPeer();
}
}
SetLogParam( pLogLevel, pLogOutput );
// Load Address List
if ((AddressFile = (char*)ConfigMember->GetChStr( "AddressList/Path", NULL )))
{
if (JSONparser->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, JSONparser->GetError() );
}
//JSONparser->WriteToScreen( pAddressListPath, 2 );
}
// Configure Selector
if ((TempMember = ConfigMember->GetChild( "Selector" )))
{
// Create Selector
Selector = new CSelect( (int)TempMember->GetChInt( "Wait", 5, true ), LogLevel );
}
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -223,117 +203,220 @@ bool CApplication::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CApplication::Init() bool CApplication::InitApplication()
{ {
// Report status CDataMember * CoreConfig;
if (Log) Log->Message( LogLevel, dlLow, "%s: Application Initialised", ProcessName ); CDataMember * ItemConfig;
CDataMember * SelectConfig;
EDebugLevel pLogLevel;
int pLogOutput;
char * TempStr;
return true; // Get Core definition
} CoreConfig = Definition->GetChild( "Core", true );
//---------------------------------------------------------------------------
bool CApplication::InitConfig( const char * pConfigPath ) // Get debug level
{ pLogLevel = dlNone;
// Check if Datatree exists TempStr = (char*)CoreConfig->GetChStr( "Log/Level", "Medium", true );
if (!DataTree || !(ConfigMember = DataTree->GetChild( pConfigPath ))) { if (TempStr)
return false; {
if (!strcasecmp( TempStr, "Low" ))
pLogLevel = dlLow;
else if (!strcasecmp( TempStr, "Medium" ))
pLogLevel = dlMedium;
else if (!strcasecmp( TempStr, "High" ))
pLogLevel = dlHigh;
} }
// LoadConfiguration // Set debug output
LoadConfigData(); pLogOutput = 0;
Init(); ItemConfig = CoreConfig->GetChild( "Log/Output[0]", true ); // Create first element if not exist
while (ItemConfig)
{
if ((TempStr = (char*)ItemConfig->GetStr( "Normal" ))) // Set default value "Normal" if not set
{
if (!strcasecmp( TempStr, "Normal")) // Normal ASCII -> Unless "AsIs", print special chars as "."
pLogOutput |= OUT_NORMAL;
else if (!strcasecmp( TempStr, "Bin")) // Print as Binary value ('1' and '0')
pLogOutput |= OUT_BIN;
else if (!strcasecmp( TempStr, "Hex")) // Print as Hexadecimal value (0-9,A-F)
pLogOutput |= OUT_HEX;
else if (!strcasecmp( TempStr, "Count")) // Print number of characters
pLogOutput |= OUT_COUNT;
else if (!strcasecmp( TempStr, "AsIs")) // Use with "Normal" -> Do not print special chars as "."
pLogOutput |= OUT_ASIS;
else if (!strcasecmp( TempStr, "CRLF")) // Add \r\n at end of line if not present
pLogOutput |= OUT_CRLF;
else
pLogOutput |= OUT_NORMAL;
}
ItemConfig = ItemConfig->GetNextPeer();
}
SetLogParam( pLogLevel, pLogOutput );
// Configure Selector
if ((SelectConfig = CoreConfig->GetChild( "Selector" ))) {
Selector = new CSelect( (int)SelectConfig->GetChInt( "Wait", 5, true ), LogLevel );
}
// Show status
if (Log) Log->Message( LogLevel, dlLow, "%s: Application Core configured.", ProcessName );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CApplication::InitFunctions( const char * pConfigPath ) bool CApplication::InitFunction( CFunctionCore * Function )
{ {
char FunctionPath[100];
CDataMember * FunctionConfig = NULL;
// Validate
if (!Function)
return false;
// Load configuration
sprintf( FunctionPath, "FunctionBlocks/%s", Function->GetName() );
if (!(FunctionConfig = Definition->GetChild( FunctionPath, true ))) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Function '%s' - Type '%s' cannot create config!",
ProcessName, Function->GetName(), Function->GetType() );
}
// Configure Function
else if (!Function->Init( FunctionConfig )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Function '%s' - Type '%s' init failed!",
ProcessName, Function->GetName(), Function->GetType() );
return false;
}
else {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Function '%s' - Type '%s' configured.",
ProcessName, Function->GetName(), Function->GetType() );
}
return true;
}
//---------------------------------------------------------------------------
bool CApplication::InitFunctions()
{
CDataMember * FunctionList;
CDataMember * FunctionConfig;
CFunctionCore * Function; CFunctionCore * Function;
CDataMember * TempMember;
char * Type; char * Type;
// Check of path exists // Check of path exists
if (!DataTree || !(FunctionConfigMember = DataTree->GetChild( pConfigPath ))) if (!(FunctionList = Definition->GetChild( "FunctionBlocks" ))) {
if (Log) Log->Message( LogLevel, dlLow, "%s: No Function Block specified", ProcessName );
return false; return false;
}
// Process each Channel // Process each Channel
TempMember = FunctionConfigMember->GetFirstChild(); FunctionConfig = FunctionList->GetFirstChild();
while (TempMember) while (FunctionConfig)
{ {
// Get function parameters // Get function parameters
Type = (char*)TempMember->GetChStr( "Type", "Custom", true ); Type = (char*)FunctionConfig->GetChStr( "Type", "Custom", true );
if (Log) Log->Message( LogLevel, dlLow, "%s: Function '%s' - Type '%s' initialising...",
ProcessName, FunctionConfig->GetName(), Type );
// Get or create function // Get or create function
if (!strcasecmp( Type, "WatchdogClient" )) { Function = AddFunction( Type, FunctionConfig->GetName() );
Function = new CWatchdogCore( TempMember->GetName() );
}
else if (!strcasecmp( Type, "Selectable" )) {
Function = new CSelectableCore( TempMember->GetName() );
}
else if (!strcasecmp( Type, "File" )) {
Function = new CFileCore( TempMember->GetName() );
}
else {
Function = GetFunction( TempMember->GetName() );
}
// Load Function configuration and Initialise // Load Function configuration and Initialise
if (Function) { if (!Function) {
Function->InitConfig( TempMember ); if (Log) Log->Message( LogLevel, dlMedium, "%s: Function '%s' - Type '%s' not found!",
ProcessName, FunctionConfig->GetName(), Type );
}
else if (!Function->Init( FunctionConfig )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Function '%s' - Type '%s' init failed!",
ProcessName, Function->GetName(), Function->GetType() );
}
else {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Function '%s' - Type '%s' configured.",
ProcessName, Function->GetName(), Function->GetType() );
} }
// Next // Next
TempMember = TempMember->GetNextPeer(); FunctionConfig = FunctionConfig->GetNextPeer();
} }
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CApplication::InitFunctionLinks( const char * pConfigPath ) bool CApplication::InitFunctionLinks()
{ {
CDataMember * LinkList;
CDataMember * LinkConfig;
TFunctionItem * FunctionItem; TFunctionItem * FunctionItem;
CDataMember * TempMember;
// Check of path exists // Check of path exists
if (!DataTree || !(LinkConfigMember = DataTree->GetChild( pConfigPath ))) if (!(LinkList = Definition->GetChild( "ChannelLinks", true ))) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: No Function Channel links specified.", ProcessName );
return false; return false;
}
else {
if (Log) Log->Message( LogLevel, dlLow, "%s: Linking Function Block Channels...", ProcessName );
}
// Process each Channel // Process each Channel
FunctionItem = FirstFunction; FunctionItem = FirstFunction;
while (FunctionItem) while (FunctionItem)
{ {
// Build links for function // Build links for function
if ((TempMember = LinkConfigMember->GetChild( FunctionItem->Function->GetName() ))) if ((LinkConfig = LinkList->GetChild( FunctionItem->Function->GetName() )))
FunctionItem->Function->InitChannelLinks( TempMember ); FunctionItem->Function->InitChannelLinks( LinkConfig );
// Next // Next
FunctionItem = FunctionItem->Next; FunctionItem = FunctionItem->Next;
} }
if (Log) Log->Message( LogLevel, dlLow, "%s: Function Block Channels linked.", ProcessName );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CApplication::AddFunctionType( const char * Type, FFuncConstructor Constructor )
{
TFunctionType ** FunctionType;
// Get end of list
FunctionType = &FirstFunctionType;
while (*FunctionType)
FunctionType = &((*FunctionType)->Next);
// Add new Type
*FunctionType = (TFunctionType*)calloc( sizeof(TFunctionType), 1 );
(*FunctionType)->Name = (char*)malloc( strlen(Type)+1 );
strcpy( (*FunctionType)->Name, Type );
(*FunctionType)->Constructor = Constructor;
return true;
};
//---------------------------------------------------------------------------
// Build List // Build List
bool CApplication::AddFunction( CFunctionCore * Function ) CFunctionCore * CApplication::AddFunction( const char * Type, const char * Name )
{ {
TFunctionItem ** FunctionPtr; TFunctionItem ** FunctionPtr;
TFunctionType * FunctionType;
// Check if unique, else get end of list // Check if unique, else get end of list
FunctionPtr = &FirstFunction; FunctionPtr = &FirstFunction;
while (*FunctionPtr && strcasecmp( (*FunctionPtr)->Function->GetName(), Function->GetName() )) while (*FunctionPtr && strcasecmp( (*FunctionPtr)->Function->GetName(), Name ))
FunctionPtr = &((*FunctionPtr)->Next); FunctionPtr = &((*FunctionPtr)->Next);
if (*FunctionPtr) return NULL; // Can't overwrite existing function
// Check if exists // Check if type is valid
if (*FunctionPtr) FunctionType = FirstFunctionType;
return false; while (FunctionType && strcasecmp( FunctionType->Name, Type ))
FunctionType = FunctionType->Next;
if (!FunctionType) return NULL; // Type not defined
// Add to end of list // Add to end of list
*FunctionPtr = (TFunctionItem*)calloc( sizeof(TFunctionItem), 1 ); *FunctionPtr = (TFunctionItem*)calloc( sizeof(TFunctionItem), 1 );
(*FunctionPtr)->Function = Function; (*FunctionPtr)->Function = FunctionType->Constructor( Name );
return true; return (*FunctionPtr)->Function;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -23,16 +23,25 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Preview // Preview
typedef struct SFunctionType TFunctionType;
typedef struct SFunctionItem TFunctionItem; typedef struct SFunctionItem TFunctionItem;
typedef CFunctionCore * (*FFuncConstructor)( const char * Name );
class Application; class Application;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
struct SFunctionType {
char * Name;
FFuncConstructor Constructor;
TFunctionType * Next;
};
//---------------------------------------------------------------------------
struct SFunctionItem struct SFunctionItem
{ {
CFunctionCore * Function; CFunctionCore * Function;
SFunctionItem * Next; SFunctionItem * Next;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -42,50 +51,54 @@ class CApplication
protected: protected:
// Variables used for configuration // Variables used for configuration
char * ConfigFile; char * ConfigFile;
char * DefinitionFile;
char * AddressFile; char * AddressFile;
// Configuration
CDataMember * DataTree;
CJSONparse * JSONparser = NULL;
// List // List
TFunctionType * FirstFunctionType;
TFunctionItem * FirstFunction; TFunctionItem * FirstFunction;
// Output // Output
EDebugLevel LogLevel; EDebugLevel LogLevel;
int LogOutput; int LogOutput;
// Configuration
CDataMember * ConfigMember;
CDataMember * FunctionConfigMember;
CDataMember * LinkConfigMember;
bool LoadConfigData();
public: public:
// Public function vars // Public function vars
CDataMember * DataTree;
CLogCore * Log; CLogCore * Log;
CSelect * Selector; CSelect * Selector;
CJSONparse * JSONparser = NULL;
// Configuration
CDataMember * Config;
CDataMember * Definition;
CDataMember * AddressList;
// Life Cycle // Life Cycle
CApplication( EDebugLevel pDebugLevel ); CApplication( EDebugLevel pDebugLevel );
virtual ~CApplication(); virtual ~CApplication();
// Manage Config File // Manage Config File
bool ReadParam( int argc, char *argv[] );
void GetProcessName( char ** ProcessName, char * pFilePath ); void GetProcessName( char ** ProcessName, char * pFilePath );
bool LoadConfig( int argc, char *argv[], const char * pConfigPath ); bool LoadConfig();
bool SaveConfig(); bool SaveConfig();
// Manually set configuration // Manually set configuration
bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay ); bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay );
// Init application // Init application
virtual bool Init(); bool InitApplication();
bool InitFunctions();
bool InitConfig( const char * pConfigPath ); bool InitFunction( CFunctionCore * Function );
bool InitFunctions( const char * pConfigPath ); bool InitFunctionLinks();
bool InitFunctionLinks( const char * pConfigPath );
// Manage Functions // Manage Functions
bool AddFunction( CFunctionCore * Function ); bool AddFunctionType( const char * Type, FFuncConstructor Constructor );
CFunctionCore * AddFunction( const char * Type, const char * Name );
CFunctionCore * GetFunction( const char * Name ); CFunctionCore * GetFunction( const char * Name );
// Run Application // Run Application

View File

@@ -226,7 +226,7 @@ CDataMember * CDataMember::GetChild( const char * Path, bool Create )
// Create element if needed // Create element if needed
if (!*Child && Create) { if (!*Child && Create) {
if ((Index == -1) || (Index = Count + 1)) { if ((Index == -1) || (Index == Count)) {
*Child = new CDataMember( Member, NULL ); *Child = new CDataMember( Member, NULL );
} }
} }
@@ -271,35 +271,41 @@ CDataMember * CDataMember::GetChild( const char * Path, bool Create )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CDataMember * CDataMember::GetChFirstChild( const char * Path ) CDataMember * CDataMember::GetChFirstChild( const char * Path, bool Create )
{ {
CDataMember * Member = NULL; CDataMember * Member = NULL;
// Find member // Find member
Member = (!Path || !*Path)? this : GetChild( Path, false ); Member = (!Path || !*Path)? this : GetChild( Path, Create );
// Check if valid type // Check if valid type
if (!Member || ((Member->Type != jtObject) && (Member->Type != jtNull))) { if (!Member || ((Member->Type != jtObject) && (Member->Type != jtNull))) {
return NULL; return NULL;
} }
else if (Create && (Member->Type == jtNull)) {
Member->SetObject(); // Set newly created member to object
}
return Member->FirstChild; return Member->FirstChild;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CDataMember * CDataMember::GetChElement( const char * Path, const int Index ) CDataMember * CDataMember::GetChElement( const char * Path, const int Index, bool Create )
{ {
CDataMember * Member = NULL; CDataMember * Member = NULL;
CDataMember * Child = NULL; CDataMember * Child = NULL;
int Count; int Count;
// Find Member // Find Member
Member = (!Path || !*Path)? this : GetChild( Path, false ); Member = (!Path || !*Path)? this : GetChild( Path, Create );
// Check if valid type // Check if valid type
if (!Member || ((Member->Type != jtArray) && (Member->Type != jtNull))) { if (!Member || ((Member->Type != jtArray) && (Member->Type != jtNull))) {
return NULL; return NULL;
} }
else if (Create && (Member->Type == jtNull)) {
Member->SetArray(); // Set newly created member to array
}
// Find element at position // Find element at position
Count = 0; Count = 0;
@@ -526,7 +532,7 @@ const char * CDataMember::GetChStr( const char * Path, const char * Default, boo
return Member->Value; return Member->Value;
} }
else if (Member && Create && (Member->Type == jtNull)) { else if (Member && Create && (Member->Type == jtNull)) {
Member->SetValue( jtString, Default ); Member->SetStr( Default );
return Member->Value; return Member->Value;
} }
else { else {
@@ -546,7 +552,7 @@ const char * CDataMember::GetChStr( const char * Path, int &Len, const char * De
return Member->Value; return Member->Value;
} }
else if (Member && Create && (Member->Type == jtNull)) { else if (Member && Create && (Member->Type == jtNull)) {
Member->SetValue( jtString, Default ); Member->SetStr( Default );
Len = Member->Len; Len = Member->Len;
return Member->Value; return Member->Value;
} }

View File

@@ -67,11 +67,11 @@ public:
const int GetLen( const char * Path ); const int GetLen( const char * Path );
CDataMember * GetChild( const char * Path, bool Create = false ); CDataMember * GetChild( const char * Path, bool Create = false );
CDataMember * GetChFirstChild( const char * Path ); CDataMember * GetChFirstChild( const char * Path, bool Create = false );
CDataMember * GetChElement( const char * Path, const int Index ); CDataMember * GetChElement( const char * Path, const int Index, bool Create = false );
inline CDataMember * GetFirstChild() { return FirstChild; }; inline CDataMember * GetFirstChild() { return GetChFirstChild( NULL, false ); };
inline CDataMember * GetElement( const int Index ) { return GetChElement( NULL, Index ); }; inline CDataMember * GetElement( const int Index ) { return GetChElement( NULL, Index, false ); };
inline CDataMember * GetParent() { return Parent; }; inline CDataMember * GetParent() { return Parent; };
inline CDataMember * GetPrevPeer() { return PrevPeer; }; inline CDataMember * GetPrevPeer() { return PrevPeer; };
@@ -83,11 +83,11 @@ public:
const long GetChInt( const char * Path, long Default = 0, bool Create = false, const char * Mask = NULL ); const long GetChInt( const char * Path, long Default = 0, bool Create = false, const char * Mask = NULL );
const double GetChFloat( const char * Path, double Default = 0.0, bool Create = false, const char * Mask = NULL ); const double GetChFloat( const char * Path, double Default = 0.0, bool Create = false, const char * Mask = NULL );
inline const char * GetStr( const char * Default = NULL, bool Create = false ) { return GetChStr( NULL, Default, Create ); }; inline const char * GetStr( const char * Default = NULL ) { return GetChStr( NULL, Default, false ); };
inline const char * GetStr( int &Len, const char * Default = NULL, bool Create = false ) { return GetChStr( NULL, Len, Default, Create ); }; inline const char * GetStr( int &Len, const char * Default = NULL ) { return GetChStr( NULL, Len, Default, false ); };
inline const bool GetBool( bool Default = false, bool Create = false ) { return GetChBool( NULL, Default, Create ); }; inline const bool GetBool( bool Default = false ) { return GetChBool( NULL, Default, false ); };
inline const long GetInt( long Default = 0, bool Create = false, const char * Mask = NULL ) { return GetChInt( NULL, Default, Create, Mask ); }; inline const long GetInt( long Default = 0, const char * Mask = NULL ) { return GetChInt( NULL, Default, false, Mask ); };
inline const double GetFloat( double Default = 0.0, bool Create = false, const char * Mask = NULL ) { return GetChFloat( NULL, Default, Create, Mask ); }; inline const double GetFloat( double Default = 0.0, const char * Mask = NULL ) { return GetChFloat( NULL, Default, false, Mask ); };
bool SetChBool( const char * Path, const bool Value ); bool SetChBool( const char * Path, const bool Value );
bool SetChInt( const char * Path, const long Value, const char * Mask = NULL ); bool SetChInt( const char * Path, const long Value, const char * Mask = NULL );

View File

@@ -22,8 +22,12 @@ extern char * ProcessName;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : //CFunctionCore * NewDeviceCore( const char * Name ) {
CFunctionCore( pName, pType ) // return (CFunctionCore*) new CDeviceCore( Name );
//}
//---------------------------------------------------------------------------
CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCore( pName, pType )
{ {
// Clear Parameters // Clear Parameters
FirstDevice = NULL; FirstDevice = NULL;

View File

@@ -61,6 +61,12 @@ struct SDeviceParam {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function Constructor List
#define TYPE_DEVICE "Device"
//CFunctionCore * NewDeviceCore( const char * Name );
//---------------------------------------------------------------------------
class CDeviceCore : public CFunctionCore class CDeviceCore : public CFunctionCore
{ {
protected: protected:
@@ -168,7 +174,7 @@ protected:
public: public:
// Life cycle // Life cycle
CDeviceCore( const char * pName, const char * Type = "Device" ); CDeviceCore( const char * pName, const char * pType = TYPE_DEVICE );
virtual ~CDeviceCore(); virtual ~CDeviceCore();
// Generate events // Generate events

View File

@@ -22,8 +22,13 @@ extern char * ProcessName;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CFileCore::CFileCore( const char * pName, const char * pType ) : // Function Constructor
CFunctionCore( pName, pType ) CFunctionCore * NewFileCore( const char * Name ) {
return (CFunctionCore*) new CFileCore( Name );
}
//---------------------------------------------------------------------------
CFileCore::CFileCore( const char * pName, const char * pType ) : CFunctionCore( pName, pType )
{ {
FirstFile = NULL; FirstFile = NULL;
} }

View File

@@ -35,6 +35,11 @@ struct SFileHandle
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function Constructor List
#define TYPE_FILE "File"
CFunctionCore * NewFileCore( const char * Name );
//---------------------------------------------------------------------------
class CFileCore : public CFunctionCore class CFileCore : public CFunctionCore
{ {
private: private:
@@ -60,7 +65,7 @@ private:
public: public:
// Life cycle // Life cycle
CFileCore( const char * pName, const char * pType = "File" ); CFileCore( const char * pName, const char * pType = TYPE_FILE );
virtual ~CFileCore(); virtual ~CFileCore();
// Manage files // Manage files

View File

@@ -20,8 +20,14 @@ extern CApplication * Application;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function Constructor
//CFunctionCore * NewFunctionCore( const char * Name ) {
// return new CFunctionCore( Name, "Function" );
//}
//---------------------------------------------------------------------------
// Life cycle // Life cycle
CFunctionCore::CFunctionCore( const char * pName, const char * pType ) CFunctionCore::CFunctionCore( const char * pName, const char * pType ) : Type( pType )
{ {
// Set name // Set name
if (pName) { if (pName) {
@@ -32,26 +38,9 @@ CFunctionCore::CFunctionCore( const char * pName, const char * pType )
Name = NULL; Name = NULL;
} }
// Set Type
if (pType) {
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;
// Logging // Logging
Log = Application->Log; Log = Application->Log;
LogLevel = dlNone; LogLevel = dlNone;
@@ -107,20 +96,25 @@ CFunctionCore::~CFunctionCore()
// Destroy Name // Destroy Name
if (Name) free( Name ); if (Name) free( Name );
if (Type) free( Type );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CFunctionCore::LoadConfigData() bool CFunctionCore::Init( CDataMember * FunctionConfig )
{ {
CDataMember * TempMember; // Load configuration
CDataMember * ItemConfig;
CDataMember * ChannelConfig;
EDebugLevel pLogLevel; EDebugLevel pLogLevel;
int pLogOutput; int pLogOutput;
char * TempStr; char * TempStr;
// Validate
if (!FunctionConfig )
return false;
// Get debug level // Get debug level
pLogLevel = dlNone; pLogLevel = dlNone;
TempStr = (char*)ConfigMember->GetChStr( "Log/Level", "Medium", true ); TempStr = (char*)FunctionConfig->GetChStr( "Log/Level", "Medium", true );
if (TempStr) if (TempStr)
{ {
if (!strcasecmp( TempStr, "Low" )) if (!strcasecmp( TempStr, "Low" ))
@@ -133,66 +127,63 @@ bool CFunctionCore::LoadConfigData()
// Set debug output // Set debug output
pLogOutput = 0; pLogOutput = 0;
if ((TempMember = ConfigMember->GetChild( "Log/Output", true ))) ItemConfig = FunctionConfig->GetChild( "Log/Output[0]", true ); // Create first element if not exist
while (ItemConfig)
{ {
TempMember = TempMember->GetFirstChild(); if ((TempStr = (char*)ItemConfig->GetStr( "Normal" ))) // Set default value "Normal" if not set
while (TempMember)
{ {
if ((TempStr = (char*)TempMember->GetStr())) if (!strcasecmp( TempStr, "Normal")) // Normal ASCII -> Unless "AsIs", print special chars as "."
{
if (!strcasecmp( TempStr, "Normal"))
pLogOutput |= OUT_NORMAL; pLogOutput |= OUT_NORMAL;
else if (!strcasecmp( TempStr, "Bin")) else if (!strcasecmp( TempStr, "Bin")) // Print as Binary value ('1' and '0')
pLogOutput |= OUT_BIN; pLogOutput |= OUT_BIN;
else if (!strcasecmp( TempStr, "Hex")) else if (!strcasecmp( TempStr, "Hex")) // Print as Hexadecimal value (0-9,A-F)
pLogOutput |= OUT_HEX; pLogOutput |= OUT_HEX;
else if (!strcasecmp( TempStr, "Count")) else if (!strcasecmp( TempStr, "Count")) // Print number of characters
pLogOutput |= OUT_COUNT; pLogOutput |= OUT_COUNT;
else if (!strcasecmp( TempStr, "AsIs")) else if (!strcasecmp( TempStr, "AsIs")) // Use with "Normal" -> Do not print special chars as "."
pLogOutput |= OUT_ASIS; pLogOutput |= OUT_ASIS;
else if (!strcasecmp( TempStr, "CRLF")) else if (!strcasecmp( TempStr, "CRLF")) // Add \r\n at end of line if not present
pLogOutput |= OUT_CRLF; pLogOutput |= OUT_CRLF;
else
pLogOutput |= OUT_NORMAL;
} }
ItemConfig = ItemConfig->GetNextPeer();
// Next
TempMember = TempMember->GetNextPeer();
} }
}
// Set Logging
SetLogParam( pLogLevel, pLogOutput ); SetLogParam( pLogLevel, pLogOutput );
// Load Channels // Load Channels
TempMember = ConfigMember->GetChFirstChild( "Channels" ); ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true );
while (TempMember) while (ChannelConfig)
{ {
if (TempMember->GetName()) { if (ChannelConfig->GetName()) {
AddChannel( TempMember->GetName(), AddChannel( ChannelConfig->GetName(),
TempMember->GetChBool( "InputEnabled", true, true ), ChannelConfig->GetChBool( "InputEnabled", true, true ),
TempMember->GetChBool( "OutputEnabled", false, true )); ChannelConfig->GetChBool( "OutputEnabled", false, true ));
} }
ChannelConfig = ChannelConfig->GetNextPeer();
// Next
TempMember = TempMember->GetNextPeer();
} }
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CFunctionCore::LoadChannelLinkData() bool CFunctionCore::InitChannelLinks( CDataMember * LinkConfig )
{ {
TChannel * Channel; TChannel * Channel;
CDataMember * ChannelMember; CDataMember * ChannelMember;
CDataMember * FunctionMember; CDataMember * FunctionMember;
// Validate
if (!LinkConfig)
return false;
// Process each Channel // Process each Channel
ChannelMember = LinkConfigMember->GetFirstChild(); ChannelMember = LinkConfig->GetFirstChild();
while (ChannelMember) while (ChannelMember)
{ {
if ((Channel = GetChannel( ChannelMember->GetName() ))) if ((Channel = GetChannel( ChannelMember->GetName() )))
{ {
FunctionMember = ChannelMember->GetFirstChild(); FunctionMember = ChannelMember->GetElement( 0 );
while (FunctionMember) while (FunctionMember)
{ {
// Get Parameters // Get Parameters
@@ -200,11 +191,9 @@ bool CFunctionCore::LoadChannelLinkData()
FunctionMember->GetChStr( "Function" ), FunctionMember->GetChStr( "Function" ),
FunctionMember->GetChStr( "Channel" ), FunctionMember->GetChStr( "Channel" ),
FunctionMember->GetChBool( "Bidirectional" ) ); FunctionMember->GetChBool( "Bidirectional" ) );
// Next
FunctionMember = FunctionMember->GetNextPeer(); FunctionMember = FunctionMember->GetNextPeer();
} }
} }
// Next
ChannelMember = ChannelMember->GetNextPeer(); ChannelMember = ChannelMember->GetNextPeer();
} }
@@ -212,69 +201,6 @@ bool CFunctionCore::LoadChannelLinkData()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
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->GetChild( pConfigPath, true )))
return false;
// Load configuration
LoadConfigData();
Init();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::InitConfig( CDataMember * 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->GetChild( pLinkConfigPath, true )))
return false;
// Load configuration
LoadChannelLinkData();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::InitChannelLinks( CDataMember *pLinkConfigMember )
{
// Validate
if (!DataTree || !(LinkConfigMember = pLinkConfigMember))
return false;
// Load configuration
LoadChannelLinkData();
return true;
}
//---------------------------------------------------------------------------
bool CFunctionCore::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay ) bool CFunctionCore::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay )
{ {
// Output // Output

View File

@@ -48,17 +48,18 @@ struct SChannelLink
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function Constructor
#define TYPE_FUNCTION "Function"
//CFunctionCore * NewFunctionCore( const char * Name );
//---------------------------------------------------------------------------
class CFunctionCore class CFunctionCore
{ {
protected: protected:
// Function Definition // Function Definition
const char * Type;
char * Name; char * Name;
char * Type;
// Configuration
CDataMember * DataTree;
CDataMember * ConfigMember;
CDataMember * LinkConfigMember;
// Channels // Channels
TChannel * FirstChannel; TChannel * FirstChannel;
@@ -73,35 +74,26 @@ protected:
int StoredOutputLen; int StoredOutputLen;
// Manage Channel // Manage Channel
inline TChannel * GetChannel( const char * Name ) { inline TChannel * GetChannel( const char * pName ) {
if (!Name) return NULL; if (!pName) return NULL;
TChannel * Channel = FirstChannel; TChannel * Channel = FirstChannel;
while (Channel && strcmp( Name, Channel->Name )) while (Channel && strcmp( pName, Channel->Name ))
Channel = Channel->Next; Channel = Channel->Next;
return Channel; return Channel;
} }
// Load configuration
virtual bool LoadConfigData();
virtual bool LoadChannelLinkData();
// Data Input/Output // 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 );
virtual bool PullInput( TChannel * Channel ); virtual bool PullInput( TChannel * Channel );
public: public:
// Life cycle // Life cycle
CFunctionCore( const char * pName, const char * Type ); CFunctionCore( const char * pName, const char * pType = TYPE_FUNCTION );
virtual ~CFunctionCore(); virtual ~CFunctionCore();
// Load Configuration // Load Configuration
virtual bool Init(); virtual bool Init( CDataMember * FunctionConfig );
virtual bool InitChannelLinks( CDataMember *LinkConfig );
bool InitConfig( const char * pConfigPath );
bool InitConfig( CDataMember * pConfigMember );
bool InitChannelLinks( const char * pLinkConfigPath );
bool InitChannelLinks( CDataMember *pLinkConfigMember );
// Set Parameters Manually // Set Parameters Manually
bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay ); bool SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay );

View File

@@ -819,6 +819,13 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent )
if (write( OutputHandle, "{", 1 ) < 0) if (write( OutputHandle, "{", 1 ) < 0)
return false; return false;
// Check if empty
if (Object->Len == 0) {
if (write( OutputHandle, "}", 1 ) < 0)
return false;
return true;
}
// Extend spacer // Extend spacer
if (Indent) { if (Indent) {
memset( &Spacer[SpacerLen], ' ', 2 ); memset( &Spacer[SpacerLen], ' ', 2 );
@@ -930,6 +937,13 @@ bool CJSONparse::PrintArray( CDataMember * Array, const int Indent )
if (write( OutputHandle, "[", 1 ) < 0) if (write( OutputHandle, "[", 1 ) < 0)
return false; return false;
// Check if empty
if (Array->Len == 0) {
if (write( OutputHandle, "]", 1 ) < 0)
return false;
return true;
}
// Extend spacer // Extend spacer
if (Indent) { if (Indent) {
memset( &Spacer[SpacerLen], ' ', 2 ); memset( &Spacer[SpacerLen], ' ', 2 );

View File

@@ -34,8 +34,13 @@ extern CApplication * Application;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CSelectableCore::CSelectableCore( const char * pName, const char * pType ) : // Function Constructor
CFunctionCore( pName, pType ) CFunctionCore * NewSelectableCore( const char * Name ) {
return (CFunctionCore*) new CSelectableCore( Name );
}
//---------------------------------------------------------------------------
CSelectableCore::CSelectableCore( const char * pName, const char * pType ) : CFunctionCore( pName, pType )
{ {
// Quick access // Quick access
Selector = Application->Selector; Selector = Application->Selector;
@@ -64,53 +69,47 @@ CSelectableCore::~CSelectableCore()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableCore::LoadConfigData() bool CSelectableCore::Init( CDataMember * FunctionConfig )
{ {
CDataMember * TempMember; CDataMember * HandleConfig;
CDataMember * AddressDef;
CDataMember * SerialConfig; CDataMember * SerialConfig;
THandle * Handle; THandle * Handle;
char * Type; char * Type;
char * Name; char * Name;
char Path[100];
char * Address; char * Address;
char * Port; char * Port;
char * ParityText; char * ParityText;
char * FlowCtrlText; char * FlowCtrlText;
short Parity; short Parity;
short FlowCtrl; short FlowCtrl;
short Queue;
long Delay; long Delay;
// Call Previous load config // Call Previous load config
CFunctionCore::LoadConfigData(); if (!CFunctionCore::Init( FunctionConfig ))
return false;
// Load Handles // Load Handles
if ((TempMember = ConfigMember->GetChild( "Handles", false ))) { HandleConfig = FunctionConfig->GetChFirstChild( "Handles", true );
TempMember = TempMember->GetFirstChild(); while (HandleConfig)
}
while (TempMember)
{ {
// Check if name is valid
if (!TempMember->GetName() || !*TempMember->GetName())
continue;
// Create Handle and channel link // Create Handle and channel link
Handle = CreateHandle( TempMember->GetName(), false ); Handle = CreateHandle( HandleConfig->GetName(), false );
Handle->Channel = GetChannel( TempMember->GetChStr( "Channel" ) ); Handle->Channel = GetChannel( HandleConfig->GetChStr( "Channel" ) );
Type = (char*)TempMember->GetChStr( "Type", "TCPclient", true ); Type = (char*)HandleConfig->GetChStr( "Type", "TCPclient", true );
if (!strcasecmp( Type, "Serial" )) if (!strcasecmp( Type, "Serial" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Port/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Port/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get address list value } else {
} Address = (char*)HandleConfig->GetChStr( "Port/Address", NULL, true ); // Get default value
else {
Address = (char*)TempMember->GetChStr( "Port/Address", NULL, true ); // Get default value
} }
SetSerialHandle( Handle, Address ); SetSerialHandle( Handle, Address );
// Update configuration if specified // Update configuration if specified
if ((SerialConfig = TempMember->GetChild( "Port/SerialConfig", false ))) if ((SerialConfig = HandleConfig->GetChild( "Port/SerialConfig", false )))
{ {
ParityText = (char*)SerialConfig->GetChStr( "Parity", "none", true ); ParityText = (char*)SerialConfig->GetChStr( "Parity", "none", true );
if (!strcasecmp( ParityText, "none" )) if (!strcasecmp( ParityText, "none" ))
@@ -143,117 +142,101 @@ bool CSelectableCore::LoadConfigData()
} }
else if (!strcasecmp( Type, "LinePrinter" )) else if (!strcasecmp( Type, "LinePrinter" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Port/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Port/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get address list value } else {
} Address = (char*)HandleConfig->GetChStr( "Port/Address", NULL, true ); // Get default value
else {
Address = (char*)TempMember->GetChStr( "Port/Address", NULL, true ); // Get default value
} }
SetLinePrinterHandle( Handle, Address ); SetLinePrinterHandle( Handle, Address );
} }
else if (!strcasecmp( Type, "UNIXserver" )) else if (!strcasecmp( Type, "UNIXserver" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Socket/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get AddressList Address value } else {
Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
} }
else { Queue = HandleConfig->GetChInt( "Socket/Queue", 2, true );
Address = (char*)TempMember->GetChStr( "Socket/Address", NULL, true ); // Get default Address value SetUnixHandle( Handle, ctUNIXserver, Address, Queue );
}
SetUnixHandle( Handle, ctUNIXserver, Address );
} }
else if (!strcasecmp( Type, "UNIXclient" )) else if (!strcasecmp( Type, "UNIXclient" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Socket/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get AddressList Address value } else {
Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
} }
else { SetUnixHandle( Handle, ctUNIXclient, Address, 0 );
Address = (char*)TempMember->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
}
SetUnixHandle( Handle, ctUNIXclient, Address );
} }
else if (!strcasecmp( Type, "UDPserver" )) else if (!strcasecmp( Type, "UDPserver" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Socket/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get AddressList Address value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value
sprintf( Path, "Address/%s/Port", Name ); } else {
Port = (char*)DataTree->GetChStr( Path, "0", true ); // Get AddressList Port value Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
} }
else { Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
Address = (char*)TempMember->GetChStr( "Socket/Address", NULL, true ); // Get default Address value SetSocketHandle( Handle, ctUDPserver, Address, strlcase(Port), 0, Delay );
Port = (char*)TempMember->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = TempMember->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctUDPserver, Address, strlcase(Port), Delay );
} }
else if (!strcasecmp( Type, "UDPclient" )) else if (!strcasecmp( Type, "UDPclient" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Socket/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get AddressList Address value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value
sprintf( Path, "Address/%s/Port", Name ); } else {
Port = (char*)DataTree->GetChStr( Path, "0", true ); // Get AddressList Port value Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
} }
else { Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
Address = (char*)TempMember->GetChStr( "Socket/Address", NULL, true ); // Get default Address value SetSocketHandle( Handle, ctUDPclient, Address, strlcase(Port), 0, Delay );
Port = (char*)TempMember->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = TempMember->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctUDPclient, Address, strlcase(Port), Delay );
} }
else if (!strcasecmp( Type, "TCPserver" )) else if (!strcasecmp( Type, "TCPserver" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Socket/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get AddressList Address value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value
sprintf( Path, "Address/%s/Port", Name ); } else {
Port = (char*)DataTree->GetChStr( Path, "0", true ); // Get AddressList Port value Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
} }
else { Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
Address = (char*)TempMember->GetChStr( "Socket/Address", NULL, true ); // Get default Address value Queue = HandleConfig->GetChInt( "Socket/Queue", 2, true );
Port = (char*)TempMember->GetChStr( "Socket/Port", "0", true ); // Get default Port value SetSocketHandle( Handle, ctTCPserver, Address, strlcase(Port), Queue, Delay );
}
Delay = TempMember->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctTCPserver, Address, strlcase(Port), Delay );
} }
else if (!strcasecmp( Type, "TCPclient" )) else if (!strcasecmp( Type, "TCPclient" ))
{ {
if ((Name = (char*)TempMember->GetChStr( "Socket/Name", NULL ))) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) {
sprintf( Path, "Address/%s/Address", Name ); Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value
Address = (char*)DataTree->GetChStr( Path, NULL, true ); // Get AddressList Address value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value
sprintf( Path, "Address/%s/Port", Name ); } else {
Port = (char*)DataTree->GetChStr( Path, "0", true ); // Get AddressList Port value Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
} }
else { Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
Address = (char*)TempMember->GetChStr( "Socket/Address", NULL, true ); // Get default Address value SetSocketHandle( Handle, ctTCPclient, Address, strlcase(Port), 0, Delay );
Port = (char*)TempMember->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = TempMember->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctTCPclient, Address, strlcase(Port), Delay );
} }
else if (!strcasecmp( Type, "ForkPipe" )) { else if (!strcasecmp( Type, "ForkPipe" )) {
Address = (char*)TempMember->GetChStr( "Fork/ExecPath", NULL, true ); // Get default value Address = (char*)HandleConfig->GetChStr( "Fork/ExecPath", NULL, true ); // Get default value
SetForkPipeHandle( Handle, Address ); SetForkPipeHandle( Handle, Address );
} }
// Set Auto Mange // Set Auto Manage
SetAutoManage( Handle, TempMember->GetChBool( "AutoManage/Enabled", true, true ), SetAutoManage( Handle, HandleConfig->GetChBool( "AutoManage/Enabled", true, true ),
TempMember->GetChBool( "AutoManage/Persistent", false, true ), HandleConfig->GetChBool( "AutoManage/Persistent", false, true ),
TempMember->GetChInt( "AutoManage/ReopenDelay", 2000, true ), HandleConfig->GetChInt( "AutoManage/ReopenDelay", 2000, true ),
TempMember->GetChInt( "AutoManage/CloseTimeout", 2000, true )); HandleConfig->GetChInt( "AutoManage/CloseTimeout", 2000, true ));
// Input buffer // Input buffer
SetInBuffer( Handle, TempMember->GetChInt( "InputBuffer/Size", 0 ), SetInBuffer( Handle, HandleConfig->GetChInt( "InputBuffer/Size", 0 ),
TempMember->GetChInt( "InputBuffer/Timeout", 250 ), HandleConfig->GetChInt( "InputBuffer/Timeout", 250 ),
TempMember->GetChStr( "InputBuffer/Marker", "" ), HandleConfig->GetChStr( "InputBuffer/Marker", "" ),
TempMember->GetChInt( "InputBuffer/MarkerLen", 0 ) ); HandleConfig->GetChInt( "InputBuffer/MarkerLen", 0 ) );
SetOutBuffer( Handle, TempMember->GetChInt( "OutputBuffer/Size", 0 ) ); SetOutBuffer( Handle, HandleConfig->GetChInt( "OutputBuffer/Size", 0 ) );
// Next // Next
TempMember = TempMember->GetNextPeer(); HandleConfig = HandleConfig->GetNextPeer();
} }
return true; return true;
@@ -458,7 +441,7 @@ bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableCore::SetUnixHandle( THandle * Handle, EConnectType Type, const char * FileName ) bool CSelectableCore::SetUnixHandle( THandle * Handle, EConnectType Type, const char * FileName, short Queue )
{ {
// Validate // Validate
if (!Handle || !FileName || if (!Handle || !FileName ||
@@ -478,6 +461,7 @@ bool CSelectableCore::SetUnixHandle( THandle * Handle, EConnectType Type, const
// Set name // Set name
Handle->Path = (char*)malloc( strlen(FileName)+1 ); Handle->Path = (char*)malloc( strlen(FileName)+1 );
strcpy( Handle->Path, FileName ); strcpy( Handle->Path, FileName );
Handle->Queue = Queue;
// Log event // Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Set as %s [%s]", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Set as %s [%s]",
@@ -486,7 +470,7 @@ bool CSelectableCore::SetUnixHandle( THandle * Handle, EConnectType Type, const
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay ) bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, short Queue, long ResolveDelay )
{ {
// Validate // Validate
if (!Handle || !HostName || !PortName || if (!Handle || !HostName || !PortName ||
@@ -517,6 +501,8 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
Handle->AddressList = NULL; Handle->AddressList = NULL;
Handle->AddressInfo = NULL; Handle->AddressInfo = NULL;
Handle->Queue = Queue;
// Log event // Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Set as %s [%s:%s]", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Set as %s [%s:%s]",
ProcessName, Name, Handle->Name, ConnectTypeName[Type], HostName, PortName ); ProcessName, Name, Handle->Name, ConnectTypeName[Type], HostName, PortName );
@@ -897,7 +883,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
}; };
// Create que for 5 connections // Create que for 5 connections
if (listen( Handle->FD, 5 ) < 0) if (listen( Handle->FD, Handle->Queue ) < 0)
{ {
// Log Event // Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to listen on UNIX Server socket [%s] (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to listen on UNIX Server socket [%s] (%s)",
@@ -1060,7 +1046,7 @@ THandle * CSelectableCore::OpenUNIXremoteSocket( THandle * Handle )
// Create Remote Client Handle // Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD ); sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
*RemoteClient = CreateHandle( ClientName, false ); *RemoteClient = CreateHandle( ClientName, false );
if (!SetUnixHandle( *RemoteClient, ctUNIXremote, Handle->Path )) { if (!SetUnixHandle( *RemoteClient, ctUNIXremote, Handle->Path, 0 )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - UNIX Server failed to configure Remote Client connection (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - UNIX Server failed to configure Remote Client connection (%s)",
ProcessName, Name, Handle->Name, strerror(errno) ); ProcessName, Name, Handle->Name, strerror(errno) );
return NULL; return NULL;
@@ -1286,7 +1272,7 @@ THandle * CSelectableCore::OpenUDPremoteSocket( THandle * Handle, char * ClientA
// Create Remote Client Handle // Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientCount ); sprintf( ClientName, "%s-%d", Handle->Name, ClientCount );
*RemoteClient = CreateHandle( ClientName, false ); *RemoteClient = CreateHandle( ClientName, false );
if (!SetSocketHandle( *RemoteClient, ctUDPremote, ClientAddress, ClientPort, 0 )) { if (!SetSocketHandle( *RemoteClient, ctUDPremote, ClientAddress, ClientPort, 0, 0 )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - UDP Server failed to configure Remote Client connection (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - UDP Server failed to configure Remote Client connection (%s)",
ProcessName, Name, Handle->Name, strerror(errno) ); ProcessName, Name, Handle->Name, strerror(errno) );
return NULL; return NULL;
@@ -1442,7 +1428,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
}; };
// Create que for 5 connections // Create que for 5 connections
if (listen( Handle->FD, 5 ) < 0) if (listen( Handle->FD, Handle->Queue ) < 0)
{ {
// Log Event // Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to listen on TCP Server socket [%s:%s] (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to listen on TCP Server socket [%s:%s] (%s)",
@@ -1524,7 +1510,7 @@ THandle * CSelectableCore::OpenTCPremoteSocket( THandle * Handle )
// Create Remote Client Handle // Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD ); sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
*RemoteClient = CreateHandle( ClientName, false ); *RemoteClient = CreateHandle( ClientName, false );
if (!SetSocketHandle( *RemoteClient, ctTCPremote, ClientAddress, ClientPort, 0 )) { if (!SetSocketHandle( *RemoteClient, ctTCPremote, ClientAddress, ClientPort, 0, 0 )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - TCP Server failed to configure Remote Client connection (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - TCP Server failed to configure Remote Client connection (%s)",
ProcessName, Name, Handle->Name, strerror(errno) ); ProcessName, Name, Handle->Name, strerror(errno) );
return NULL; return NULL;

View File

@@ -100,6 +100,7 @@ struct SHandle {
struct addrinfo * AddressList; // List of resolved IP Addresses for host name struct addrinfo * AddressList; // List of resolved IP Addresses for host name
struct addrinfo * AddressInfo; // Current selected IP Address struct addrinfo * AddressInfo; // Current selected IP Address
bool AddressFailed; // Indicate failure to connect to address bool AddressFailed; // Indicate failure to connect to address
short Queue; // Max waiting connections
long ResolveDelay; // Delay before resolving hostname via DNS long ResolveDelay; // Delay before resolving hostname via DNS
// Serial Port config // Serial Port config
@@ -173,6 +174,12 @@ public:
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function Constructor
#define TYPE_SELECTABLE "Selectable"
CFunctionCore * NewSelectableCore( const char * Name );
//---------------------------------------------------------------------------
class CSelectableCore : public CFunctionCore class CSelectableCore : public CFunctionCore
{ {
protected: protected:
@@ -182,9 +189,6 @@ protected:
// Select interface // Select interface
CSelect * Selector; CSelect * Selector;
// Configuration
virtual bool LoadConfigData();
// Managing File Handles // Managing File Handles
bool RemoveHandle( THandle * Handle ); bool RemoveHandle( THandle * Handle );
bool DestroyHandle( THandle * Handle ); bool DestroyHandle( THandle * Handle );
@@ -248,9 +252,12 @@ protected:
public: public:
// Life Cycle // Life Cycle
CSelectableCore( const char * Name, const char * pType = "Selectable" ); CSelectableCore( const char * Name, const char * Type = TYPE_SELECTABLE );
virtual ~CSelectableCore(); virtual ~CSelectableCore();
// Configuration
virtual bool Init( CDataMember * FunctionConfig );
// Finding Handles // Finding Handles
inline THandle * GetHandle( const char * HandleName ) inline THandle * GetHandle( const char * HandleName )
{ {
@@ -281,8 +288,8 @@ public:
bool SetSerialHandleConfig( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait ); bool SetSerialHandleConfig( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait );
bool SetLinePrinterHandle( THandle * Handle, const char * FileName ); bool SetLinePrinterHandle( THandle * Handle, const char * FileName );
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath ); bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
bool SetUnixHandle( THandle * Handle, EConnectType Type, const char * FileName ); bool SetUnixHandle( THandle * Handle, EConnectType Type, const char * FileName, short Queue );
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay ); bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, short Queue, long ResolveDelay );
bool ClearHandle( THandle * Handle ); bool ClearHandle( THandle * Handle );
// FD Operations // FD Operations

View File

@@ -20,8 +20,13 @@ extern char * ProcessName;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CWatchdogCore::CWatchdogCore( const char * pName ) : // Function Constructor
CSelectableCore( pName, "WatchdogClient" ) CFunctionCore * NewWatchdogCore( const char * Name ) {
return (CFunctionCore*) new CWatchdogCore( Name );
}
//---------------------------------------------------------------------------
CWatchdogCore::CWatchdogCore( const char * pName, const char * pType ) : CSelectableCore( pName, pType )
{ {
// Create protocol // Create protocol
Protocol = new CLiteProtocol( 50, '\x02', '\x03', '\x00' ); Protocol = new CLiteProtocol( 50, '\x02', '\x03', '\x00' );
@@ -44,18 +49,6 @@ CWatchdogCore::~CWatchdogCore()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CWatchdogCore::LoadConfigData()
{
// Call Previous load config
CSelectableCore::LoadConfigData();
// Set specific parameters
SetInterval( ConfigMember->GetChInt( "Parameters/PingInterval", 500, true ));
return true;
}
//---------------------------------------------------------------------------
bool CWatchdogCore::SetInterval( int pPingInterval ) bool CWatchdogCore::SetInterval( int pPingInterval )
{ {
PingInterval = pPingInterval; PingInterval = pPingInterval;
@@ -63,14 +56,20 @@ bool CWatchdogCore::SetInterval( int pPingInterval )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CWatchdogCore::Init() bool CWatchdogCore::Init( CDataMember * FunctionConfig )
{ {
// Call Previous ingi
if (!CSelectableCore::Init( FunctionConfig ))
return false;
// Set specific parameters
SetInterval( FunctionConfig->GetChInt( "Parameters/PingInterval", 500, true ));
// Create handle and set reference, if not done // Create handle and set reference, if not done
if (!(Ping = GetHandle( "Ping" ))) if (!(Ping = GetHandle( "Ping" )))
Ping = CreateHandle( "Ping", false ); Ping = CreateHandle( "Ping", false );
// Previous init return true;
return CSelectableCore::Init();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -17,6 +17,12 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function Constructor
#define TYPE_WATCHDOG "Watchdog"
CFunctionCore * NewWatchdogCore( const char * Name );
//---------------------------------------------------------------------------
class CWatchdogCore : public CSelectableCore class CWatchdogCore : public CSelectableCore
{ {
private: private:
@@ -32,17 +38,14 @@ private:
public: public:
// Life Cycle // Life Cycle
CWatchdogCore( const char * pName ); CWatchdogCore( const char * pName, const char * pType = TYPE_WATCHDOG );
virtual ~CWatchdogCore(); virtual ~CWatchdogCore();
// Load Configuration
virtual bool LoadConfigData();
// Manually set Configuration // Manually set Configuration
bool SetInterval( int pPingInterval ); bool SetInterval( int pPingInterval );
// Initialisation // Initialisation
virtual bool Init(); virtual bool Init( CDataMember * FunctionConfig );
// Process // Process
virtual bool Process(); virtual bool Process();