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:
Charl Wentzel
2017-11-21 10:15:26 +02:00
parent c023cec697
commit 9f7e1b486e
6 changed files with 109 additions and 101 deletions

View File

@@ -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 )

View File

@@ -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 );

View File

@@ -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();
};

View File

@@ -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);
}
//---------------------------------------------------------------------------

View File

@@ -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);
};
//---------------------------------------------------------------------------

View File

@@ -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 );