From 9f7e1b486e35b127889df8cded200c67799376c0 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Tue, 21 Nov 2017 10:15:26 +0200 Subject: [PATCH] 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 --- CMakeLists.txt | 2 +- SelectableCore.cpp | 86 ++++++++++++++++++++++++++++++++++------------ SelectableCore.h | 3 +- TimingCore.cpp | 68 ------------------------------------ TimingCore.h | 47 +++++++++++++++++++++---- WatchdogCore.cpp | 4 +-- 6 files changed, 109 insertions(+), 101 deletions(-) delete mode 100644 TimingCore.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b09ddb1..2c39d4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 383b1dd..ce7daf4 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.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 ) { - THandle * Handle = NULL; - THandle * ChildHandle = NULL; + TChannel * Channel = NULL; + THandle * Handle = 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; } + // 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 (!Channel->InputEnabled) { + // Channel disabled + if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName ); + return 0; + } + + // Log event + if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Channel '%s' - IN:", Name, ChannelName ); + // Find Linked handle Handle = FirstHandle; - while( Handle && (!Handle->Channel || strcasecmp( ChannelName, Handle->Channel->Name ))) { + 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; } - // Check if any handle found - if (!Handle) { + if (!HandleCount) { // Handle not found - if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not found", Name, ChannelName ); + if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, No Handles not found", Name, ChannelName ); return 0; } - else if (!Handle->Channel->InputEnabled) { - // Handle is not open - if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName ); - return 0; - } - else if ((Handle->State != csOpen)) + + 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 ); + // Check if Handle is open + 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 ); diff --git a/SelectableCore.h b/SelectableCore.h index 80f1d9e..8faab32 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -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(); }; diff --git a/TimingCore.cpp b/TimingCore.cpp deleted file mode 100644 index d38481e..0000000 --- a/TimingCore.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * TimingCore.cpp - * - * Created on: 13 May 2016 - * Author: wentzelc - */ - -// Standard C/C++ Libraries -#include -#include - -// 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); -} -//--------------------------------------------------------------------------- - diff --git a/TimingCore.h b/TimingCore.h index 87f1150..8718f6e 100644 --- a/TimingCore.h +++ b/TimingCore.h @@ -10,20 +10,53 @@ // Standard C/C++ Libraries #include +#include +#include // 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); +}; //--------------------------------------------------------------------------- diff --git a/WatchdogCore.cpp b/WatchdogCore.cpp index 4e5847c..a015089 100644 --- a/WatchdogCore.cpp +++ b/WatchdogCore.cpp @@ -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 );