Important Update:
- SelectableCore: - Split handling of Handle from Input() to InputHandle() method - Allow multiple handles to be connected to single Channel - Update logs to report Handle, not Channel name - TimingCore: - Convert all functions to inline functions in header (remove .cpp file) - Add new function TimeLeft() - WatchdogCore: - Bug fix: No watchdog channel, use InputHandle() method not Input() - Bug fix: ping ignored, use To:"watchdog" in ping command
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
PROJECT(lib_redAcore)
|
PROJECT(lib_redAcore)
|
||||||
|
|
||||||
ADD_LIBRARY(redAcore TimingCore.cpp DateTimeCore.cpp LogCore.cpp SignalCore.cpp DataTreeCore.cpp JSONparseCore.cpp CharBufferCore.cpp
|
ADD_LIBRARY(redAcore DateTimeCore.cpp LogCore.cpp SignalCore.cpp DataTreeCore.cpp JSONparseCore.cpp CharBufferCore.cpp
|
||||||
LiteProtocolCore.cpp ItemBufferCore.cpp EventBufferCore.cpp
|
LiteProtocolCore.cpp ItemBufferCore.cpp EventBufferCore.cpp
|
||||||
ApplicationCore.cpp FunctionCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp WatchdogCore.cpp DeviceCore.cpp )
|
ApplicationCore.cpp FunctionCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp WatchdogCore.cpp DeviceCore.cpp )
|
||||||
|
|||||||
@@ -1364,8 +1364,10 @@ int CSelectableCore::WriteToFD( int FD, const char * Data, int Len, bool Force )
|
|||||||
|
|
||||||
int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len )
|
int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len )
|
||||||
{
|
{
|
||||||
|
TChannel * Channel = NULL;
|
||||||
THandle * Handle = NULL;
|
THandle * Handle = NULL;
|
||||||
THandle * ChildHandle = NULL;
|
int HandleCount = 0;
|
||||||
|
int TempWritten = 0;
|
||||||
int BytesWritten = 0;
|
int BytesWritten = 0;
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
@@ -1373,49 +1375,89 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find Linked handle
|
// Get Channel
|
||||||
Handle = FirstHandle;
|
if (!(Channel = GetChannel( ChannelName ))) {
|
||||||
while( Handle && (!Handle->Channel || strcasecmp( ChannelName, Handle->Channel->Name ))) {
|
// Channel not found
|
||||||
Handle = Handle->Next;
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel not found", Name, ChannelName );
|
||||||
}
|
|
||||||
|
|
||||||
// Check if any handle found
|
|
||||||
if (!Handle) {
|
|
||||||
// Handle not found
|
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not found", Name, ChannelName );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (!Handle->Channel->InputEnabled) {
|
else if (!Channel->InputEnabled) {
|
||||||
// Handle is not open
|
// Channel disabled
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName );
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if ((Handle->State != csOpen))
|
|
||||||
|
// Log event
|
||||||
|
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Channel '%s' - IN:", Name, ChannelName );
|
||||||
|
|
||||||
|
// Find Linked handle
|
||||||
|
Handle = FirstHandle;
|
||||||
|
while( Handle )
|
||||||
|
{
|
||||||
|
if (Handle->Channel && !strcasecmp( ChannelName, Handle->Channel->Name ))
|
||||||
|
{
|
||||||
|
// Input to Handle
|
||||||
|
TempWritten = InputHandle( Handle, Data, Len );
|
||||||
|
BytesWritten = (TempWritten > BytesWritten)? TempWritten : BytesWritten;
|
||||||
|
HandleCount++;
|
||||||
|
}
|
||||||
|
Handle = Handle->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HandleCount) {
|
||||||
|
// Handle not found
|
||||||
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, No Handles not found", Name, ChannelName );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BytesWritten;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CSelectableCore::InputHandle( THandle * Handle, const char * Data, int Len )
|
||||||
|
{
|
||||||
|
THandle * ChildHandle = NULL;
|
||||||
|
int BytesWritten = 0;
|
||||||
|
|
||||||
|
if ((Handle->State != csOpen))
|
||||||
{
|
{
|
||||||
// Check if auto-managed handle
|
// Check if auto-managed handle
|
||||||
if (!Handle->AutoManage)
|
if (!Handle->AutoManage)
|
||||||
{
|
{
|
||||||
// Handle is not open or auto-managed
|
// Handle is not open or auto-managed
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not Open (not auto-managed)", Name, ChannelName );
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Handle not Open (not auto-managed)", Name, Handle->Name );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Try to Open handle
|
// Check duration since last PortIn
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input held, Trying to open (auto-managed) Handle", Name, ChannelName );
|
if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))
|
||||||
Open( Handle );
|
{
|
||||||
|
// Complete opening process
|
||||||
|
if (Open( Handle ) == -1) {
|
||||||
|
// Reset Timer
|
||||||
|
SetStartTime( &(Handle->ReopenStart) );
|
||||||
|
}
|
||||||
|
|
||||||
// Check if Handle is open
|
// Check if Handle is open
|
||||||
if (Handle->State != csOpen) {
|
if (Handle->State == csWaitingtoOpen) {
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not Open", Name, ChannelName );
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Waiting to open (auto-managed) Handle", Name, Handle->Name );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (Handle->State != csOpen) {
|
||||||
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, (auto-managed) Handle failed to Open", Name, Handle->Name );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Retry (auto-managed) Handle re-open in %d ms", Name, Handle->Name,
|
||||||
|
TimeLeft( Handle->ReopenStart, Handle->ReopenDelay) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log event
|
|
||||||
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Channel '%s' - IN:", Name, ChannelName );
|
|
||||||
|
|
||||||
// Check packet length
|
// Check packet length
|
||||||
if (Len == -1) {
|
if (Len == -1) {
|
||||||
Len = strlen( Data );
|
Len = strlen( Data );
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ public:
|
|||||||
|
|
||||||
// Function Interface
|
// Function Interface
|
||||||
virtual int Input( const char * ChannelName, const char * Buffer, int BufLen = -1 );
|
virtual int Input( const char * ChannelName, const char * Buffer, int BufLen = -1 );
|
||||||
|
int InputHandle( THandle * Handle, const char * Data, int Len );
|
||||||
virtual bool Process();
|
virtual bool Process();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* TimingCore.cpp
|
|
||||||
*
|
|
||||||
* Created on: 13 May 2016
|
|
||||||
* Author: wentzelc
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
|
||||||
#include <time.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
// redA Libraries
|
|
||||||
#include "TimingCore.h"
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Set time
|
|
||||||
void SetInterval( timeval * Time, long MilliSeconds )
|
|
||||||
{
|
|
||||||
// milli-seconds -> seconds
|
|
||||||
Time->tv_sec = MilliSeconds / 1000;
|
|
||||||
// milli-seconds -> micro-seconds
|
|
||||||
Time->tv_usec = (MilliSeconds % 1000) * 1000;
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Populated start time
|
|
||||||
void SetStartTime( timeval * StartTime )
|
|
||||||
{
|
|
||||||
// Get current time
|
|
||||||
gettimeofday( StartTime, NULL );
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Clear start time
|
|
||||||
void ClearStartTime( timeval * StartTime )
|
|
||||||
{
|
|
||||||
// Get current time
|
|
||||||
StartTime->tv_sec = 0;
|
|
||||||
StartTime->tv_usec = 0;
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Calculate TimePassed from Start Time (in milli-seconds)
|
|
||||||
long TimePassed( timeval StartTime )
|
|
||||||
{
|
|
||||||
timeval CurrTime;
|
|
||||||
long Duration;
|
|
||||||
|
|
||||||
// Get current time
|
|
||||||
gettimeofday( &CurrTime, NULL );
|
|
||||||
|
|
||||||
// Get time passed in milli-seconds
|
|
||||||
Duration = (CurrTime.tv_sec - StartTime.tv_sec) * (time_t)1000 +
|
|
||||||
(CurrTime.tv_usec - StartTime.tv_usec) / (time_t)1000;
|
|
||||||
if (Duration < 0)
|
|
||||||
Duration = LONG_MAX;
|
|
||||||
|
|
||||||
return Duration;
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool Timeout( timeval StartTime, long MilliSeconds )
|
|
||||||
{
|
|
||||||
return ((TimePassed(StartTime) > MilliSeconds)? true : false);
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
47
TimingCore.h
47
TimingCore.h
@@ -10,20 +10,53 @@
|
|||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
// redA Libraries
|
// redA Libraries
|
||||||
/* none */
|
/* none */
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Manage as Interval
|
// Set interval (not for timer)
|
||||||
void SetInterval( timeval *Time, long MilliSeconds );
|
inline void SetInterval( timeval * Time, long MilliSeconds ) {
|
||||||
|
Time->tv_sec = MilliSeconds / 1000;
|
||||||
|
Time->tv_usec = (MilliSeconds % 1000) * 1000;
|
||||||
|
};
|
||||||
|
|
||||||
// Manage as Timer
|
// Mark start time
|
||||||
void SetStartTime( timeval *StartTime );
|
inline void SetStartTime( timeval *StartTime ) {
|
||||||
void ClearStartTime( timeval * StartTime );
|
gettimeofday( StartTime, NULL );
|
||||||
long TimePassed( timeval StartTime );
|
};
|
||||||
bool Timeout( timeval StartTime, long MilliSeconds );
|
|
||||||
|
// Clear timer
|
||||||
|
inline void ClearStartTime( timeval * StartTime ) {
|
||||||
|
StartTime->tv_sec = 0;
|
||||||
|
StartTime->tv_usec = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Time passed since start time
|
||||||
|
inline long TimePassed( timeval StartTime ) {
|
||||||
|
timeval CurrTime;
|
||||||
|
long Duration;
|
||||||
|
|
||||||
|
gettimeofday( &CurrTime, NULL );
|
||||||
|
Duration = (CurrTime.tv_sec - StartTime.tv_sec) * (time_t)1000 +
|
||||||
|
(CurrTime.tv_usec - StartTime.tv_usec) / (time_t)1000;
|
||||||
|
if (Duration < 0)
|
||||||
|
Duration = LONG_MAX;
|
||||||
|
return Duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Time remaining from Start time to given time out
|
||||||
|
inline long TimeLeft( timeval StartTime, long MilliSeconds ) {
|
||||||
|
return (MilliSeconds - TimePassed(StartTime));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Has give time expired after start time
|
||||||
|
inline bool Timeout( timeval StartTime, long MilliSeconds ) {
|
||||||
|
return ((TimePassed(StartTime) > MilliSeconds)? true : false);
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ CWatchdogCore::CWatchdogCore( const char * pName ) :
|
|||||||
{
|
{
|
||||||
// Create protocol
|
// Create protocol
|
||||||
Protocol = new CLiteProtocol( 50, '\x01', '\x02', '\x00' );
|
Protocol = new CLiteProtocol( 50, '\x01', '\x02', '\x00' );
|
||||||
Protocol->CreateCommand( ProcessName, pName, "ping" );
|
Protocol->CreateCommand( ProcessName, "watchdog", "ping" );
|
||||||
|
|
||||||
// Start timer
|
// Start timer
|
||||||
PingInterval = 500;
|
PingInterval = 500;
|
||||||
@@ -83,7 +83,7 @@ bool CWatchdogCore::Process()
|
|||||||
if (Timeout( PingTimer, PingInterval ))
|
if (Timeout( PingTimer, PingInterval ))
|
||||||
{
|
{
|
||||||
// Send command
|
// Send command
|
||||||
Input( Ping->Name, Protocol->GetCommandStr(), Protocol->GetCommandLen() );
|
InputHandle( Ping, Protocol->GetCommandStr(), Protocol->GetCommandLen() );
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
SetStartTime( &PingTimer );
|
SetStartTime( &PingTimer );
|
||||||
|
|||||||
Reference in New Issue
Block a user