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)
|
||||
|
||||
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
|
||||
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 )
|
||||
{
|
||||
TChannel * Channel = NULL;
|
||||
THandle * Handle = NULL;
|
||||
THandle * ChildHandle = NULL;
|
||||
int HandleCount = 0;
|
||||
int TempWritten = 0;
|
||||
int BytesWritten = 0;
|
||||
|
||||
// Validate
|
||||
@@ -1373,49 +1375,89 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find Linked handle
|
||||
Handle = FirstHandle;
|
||||
while( Handle && (!Handle->Channel || strcasecmp( ChannelName, Handle->Channel->Name ))) {
|
||||
Handle = Handle->Next;
|
||||
}
|
||||
|
||||
// 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 );
|
||||
// Get Channel
|
||||
if (!(Channel = GetChannel( ChannelName ))) {
|
||||
// Channel not found
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel not found", Name, ChannelName );
|
||||
return 0;
|
||||
}
|
||||
else if (!Handle->Channel->InputEnabled) {
|
||||
// Handle is not open
|
||||
else if (!Channel->InputEnabled) {
|
||||
// Channel disabled
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName );
|
||||
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
|
||||
if (!Handle->AutoManage)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to Open handle
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input held, Trying to open (auto-managed) Handle", Name, ChannelName );
|
||||
Open( Handle );
|
||||
// Check duration since last PortIn
|
||||
if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))
|
||||
{
|
||||
// Complete opening process
|
||||
if (Open( Handle ) == -1) {
|
||||
// Reset Timer
|
||||
SetStartTime( &(Handle->ReopenStart) );
|
||||
}
|
||||
|
||||
// Check if Handle is open
|
||||
if (Handle->State != csOpen) {
|
||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not Open", Name, ChannelName );
|
||||
if (Handle->State == csWaitingtoOpen) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Channel '%s' - IN:", Name, ChannelName );
|
||||
|
||||
// Check packet length
|
||||
if (Len == -1) {
|
||||
Len = strlen( Data );
|
||||
|
||||
@@ -283,7 +283,8 @@ public:
|
||||
};
|
||||
|
||||
// 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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
// redA Libraries
|
||||
/* none */
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Manage as Interval
|
||||
void SetInterval( timeval *Time, long MilliSeconds );
|
||||
// Set interval (not for timer)
|
||||
inline void SetInterval( timeval * Time, long MilliSeconds ) {
|
||||
Time->tv_sec = MilliSeconds / 1000;
|
||||
Time->tv_usec = (MilliSeconds % 1000) * 1000;
|
||||
};
|
||||
|
||||
// Manage as Timer
|
||||
void SetStartTime( timeval *StartTime );
|
||||
void ClearStartTime( timeval * StartTime );
|
||||
long TimePassed( timeval StartTime );
|
||||
bool Timeout( timeval StartTime, long MilliSeconds );
|
||||
// Mark start time
|
||||
inline void SetStartTime( timeval *StartTime ) {
|
||||
gettimeofday( StartTime, NULL );
|
||||
};
|
||||
|
||||
// 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
|
||||
Protocol = new CLiteProtocol( 50, '\x01', '\x02', '\x00' );
|
||||
Protocol->CreateCommand( ProcessName, pName, "ping" );
|
||||
Protocol->CreateCommand( ProcessName, "watchdog", "ping" );
|
||||
|
||||
// Start timer
|
||||
PingInterval = 500;
|
||||
@@ -83,7 +83,7 @@ bool CWatchdogCore::Process()
|
||||
if (Timeout( PingTimer, PingInterval ))
|
||||
{
|
||||
// Send command
|
||||
Input( Ping->Name, Protocol->GetCommandStr(), Protocol->GetCommandLen() );
|
||||
InputHandle( Ping, Protocol->GetCommandStr(), Protocol->GetCommandLen() );
|
||||
|
||||
// Reset timer
|
||||
SetStartTime( &PingTimer );
|
||||
|
||||
Reference in New Issue
Block a user