From 14982e84592232e328482daff66171114cf97b23 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Mon, 15 Jul 2019 17:40:40 +0200 Subject: [PATCH] Important Update: - Channels (FunctionCore & SelectableBare): - Added state "Standby", allow auto-managed handle to be opened - SelectableCore: - Set default "Persistent" state for sockets based on type - Remove Process() method (no different from SelectableBare - DateTimeCore: - Added BuildDateTimeStr() methods to build date for values - JSONparseCore: - Added error message to file operations --- DateTimeCore.cpp | 51 ++++++++++++++++++-------- DateTimeCore.h | 10 ++++-- FunctionCore.h | 4 +-- JSONparseCore.cpp | 5 +-- SelectableBare.cpp | 12 +++++-- SelectableCore.cpp | 89 ++++++++++++++-------------------------------- SelectableCore.h | 1 - 7 files changed, 86 insertions(+), 86 deletions(-) diff --git a/DateTimeCore.cpp b/DateTimeCore.cpp index 8340054..ee3cf3b 100644 --- a/DateTimeCore.cpp +++ b/DateTimeCore.cpp @@ -371,6 +371,40 @@ bool ReadDateTimeStr( const char *DateTimeStr, unsigned char &Day, unsigned cha } //--------------------------------------------------------------------------- +char const * BuildDateStr( unsigned char Day, unsigned char Month, unsigned Year, const char * DateSeparator ) +{ + // Build String + sprintf( ReturnStr, "%04d%s%02d%s%02d", + Year, ((DateSeparator)? DateSeparator : ""), Month, ((DateSeparator)? DateSeparator : ""), Day ); + + // Return value + return (ReturnStr); +} +//--------------------------------------------------------------------------- + +char const * BuildTimeStr( unsigned char Hours, unsigned char Minutes, unsigned char Seconds, const char * TimeSeparator ) +{ + // Build String + sprintf( ReturnStr, "%02d%s%02d%s%02d", + Hours, ((TimeSeparator)? TimeSeparator : ""), Minutes, ((TimeSeparator)? TimeSeparator : ""), Seconds ); + + return (ReturnStr); +} +//--------------------------------------------------------------------------- + +char const * BuildDateTimeStr( unsigned char Day, unsigned char Month, unsigned Year, + unsigned char Hours, unsigned char Minutes, unsigned char Seconds, + const char * DateSeparator, const char * TimeSeparator ) +{ + // Build String + sprintf( ReturnStr, "%04d%s%02d%s%02d %02d%s%02d%s%02d", + Year, ((DateSeparator)? DateSeparator : ""), Month, ((DateSeparator)? DateSeparator : ""), Day, + Hours, ((TimeSeparator)? TimeSeparator : ""), Minutes, ((TimeSeparator)? TimeSeparator : ""), Seconds ); + + return (ReturnStr); +} +//--------------------------------------------------------------------------- + // Get the current date in a string char const * BuildDateStr( const time_t EpochTime, bool LocalTime, const char * DateSeparator ) { @@ -382,11 +416,7 @@ char const * BuildDateStr( const time_t EpochTime, bool LocalTime, const char * ReadDate( EpochTime, LocalTime, Day, Month, Year ); // Build String - sprintf( ReturnStr, "%04d%s%02d%s%02d", - Year, ((DateSeparator)? DateSeparator : ""), Month, ((DateSeparator)? DateSeparator : ""), Day ); - - // Return value - return (ReturnStr); + return BuildTimeStr( Year, Month, Day, DateSeparator ); } //--------------------------------------------------------------------------- @@ -400,10 +430,7 @@ char const * BuildTimeStr( const time_t EpochTime, bool LocalTime, const char * ReadTime( EpochTime, LocalTime, Hours, Minutes, Seconds ); // Build String - sprintf( ReturnStr, "%02d%s%02d%s%02d", - Hours, ((TimeSeparator)? TimeSeparator : ""), Minutes, ((TimeSeparator)? TimeSeparator : ""), Seconds ); - - return (ReturnStr); + return BuildTimeStr( Hours, Minutes, Seconds, TimeSeparator ); } //--------------------------------------------------------------------------- @@ -420,9 +447,5 @@ char const * BuildDateTimeStr( const time_t EpochTime, bool LocalTime, const cha ReadDateTime( EpochTime, LocalTime, Day, Month, Year, Hours, Minutes, Seconds ); // Build String - sprintf( ReturnStr, "%04d%s%02d%s%02d %02d%s%02d%s%02d", - Year, ((DateSeparator)? DateSeparator : ""), Month, ((DateSeparator)? DateSeparator : ""), Day, - Hours, ((TimeSeparator)? TimeSeparator : ""), Minutes, ((TimeSeparator)? TimeSeparator : ""), Seconds ); - - return (ReturnStr); + return BuildDateTimeStr( Year, Month, Day, Hours, Minutes, Seconds, DateSeparator, TimeSeparator ); } diff --git a/DateTimeCore.h b/DateTimeCore.h index e3992c3..b734c40 100644 --- a/DateTimeCore.h +++ b/DateTimeCore.h @@ -39,10 +39,16 @@ bool ReadDate( const time_t EpochTime, bool LocalTime, unsigned char &Day, un bool ReadDateTime( const time_t EpochTime, bool LocalTime, unsigned char &Day, unsigned char &Month, unsigned &Year, unsigned char &Hours, unsigned char &Minutes, unsigned char &Seconds ); -bool ReadTimeStr( const char *DateTimeStr, unsigned char &Hours, unsigned char &Minutes, unsigned char &Seconds, bool Maxtime ); +bool ReadTimeStr( const char *DateTimeStr, unsigned char &Hours, unsigned char &Minutes, unsigned char &Seconds, bool Maxtime = false ); bool ReadDateStr( const char *DateTimeStr, unsigned char &Day, unsigned char &Month, unsigned &Year ); bool ReadDateTimeStr( const char *DateTimeStr, unsigned char &Day, unsigned char &Month, unsigned &Year, - unsigned char &Hours, unsigned char &Minutes, unsigned char &Seconds, bool Maxtime ); + unsigned char &Hours, unsigned char &Minutes, unsigned char &Seconds, bool Maxtime = false ); + +char const * BuildDateStr( unsigned char Day, unsigned char Month, unsigned Year, const char * DateSeparator = "/" ); +char const * BuildTimeStr( unsigned char Hours, unsigned char Minutes, unsigned char Seconds, const char * TimeSeparator = ":" ); +char const * BuildDateTimeStr( unsigned char Day, unsigned char Month, unsigned Year, + unsigned char Hours, unsigned char Minutes, unsigned char Seconds, + const char * DateSeparator = "/", const char * TimeSeparator = ":" ); char const * BuildDateStr( const time_t EpochTime, bool LocalTime, const char * DateSeparator = "/" ); char const * BuildTimeStr( const time_t EpochTime, bool LocalTime, const char * TimeSeparator = ":" ); diff --git a/FunctionCore.h b/FunctionCore.h index f17bfec..c274f5c 100644 --- a/FunctionCore.h +++ b/FunctionCore.h @@ -18,8 +18,8 @@ //--------------------------------------------------------------------------- // Enumarate Types -typedef enum { CH_off = 0, CH_wait = 1, CH_ready = 2 } EChannelState; -const char ChannelStateName[][15] = { "Off", "Waiting", "Ready" }; +typedef enum { CH_off = 0, CH_standby = 1, CH_wait = 2, CH_ready = 3 } EChannelState; +const char ChannelStateName[][15] = { "Off", "Standby", "Waiting", "Ready" }; //--------------------------------------------------------------------------- diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index 1cb53a1..cbf39c4 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -8,6 +8,7 @@ // Standard C/C++ Libraries #include #include +#include // redA Libraries #include "JSONparseCore.h" @@ -145,7 +146,7 @@ bool CJSONparse::WriteToFile( const char * BasePath, const char * FilePath, cons // Open file if ((Handle = open( FilePath, O_CREAT|O_WRONLY|O_TRUNC, 0660 )) < 0) { Error = true; - sprintf( ErrorText, "Could not open file" ); + sprintf( ErrorText, "Could not open file - [%d] %s", errno, strerror(errno) ); return false; } @@ -243,7 +244,7 @@ bool CJSONparse::ReadFromFile( const char * BasePath, const char * FilePath ) // Open file if ((Handle = open( FilePath, O_RDONLY )) < 0) { Error = true; - sprintf( ErrorText, "Could not open file" ); + sprintf( ErrorText, "Could not open file - [%d] %s", errno, strerror(errno) ); return false; } diff --git a/SelectableBare.cpp b/SelectableBare.cpp index cddcfac..07e3994 100644 --- a/SelectableBare.cpp +++ b/SelectableBare.cpp @@ -175,7 +175,7 @@ bool CSelectableBare::HandleState( THandle * Handle, EConnectState State ) if (!Handle || (Handle->State == State)) return false; - // Set Call back + // Execute call back for state if (Handle->StateCallback[ (int)State ]) (Handle->StateCallback[ (int)State ])( this, Handle, State ); @@ -188,6 +188,8 @@ bool CSelectableBare::HandleState( THandle * Handle, EConnectState State ) ChannelState = CH_wait; else if ((Handle->State == csOpen) || (Handle->State == csDataWaiting)) ChannelState = CH_ready; + else if (Handle->AutoManage) + ChannelState = CH_standby; else ChannelState = CH_off; if (Handle->Channel->InState != ChannelState) @@ -677,9 +679,9 @@ int CSelectableBare::Input( const char * ChannelName, const char * SourceRef, co ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); return 0; } - else if (Channel->InState != CH_ready) { + else if (Channel->InState == CH_off) { // Channel disabled - if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready", + if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel off", ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); return 0; } @@ -822,6 +824,10 @@ bool CSelectableBare::Process() Open( Handle ); } } + else if (Handle->Channel && (Handle->Channel->InState == CH_off) && Handle->AutoManage) { + // Set channel to standby + SetChannelInState( Handle->Channel, CH_standby ); + } // Check Input buffers if (Handle->InBuffer && (Handle->InBuffer->Len() > 0)) { diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 4703eaa..814f2e5 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -114,6 +114,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) short Parity; short FlowCtrl; short Queue; + bool Persitent; // Call Previous load config if (!CFunctionCore::Init( FunctionConfig )) @@ -170,6 +171,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) SerialConfig->GetChInt( "DataBits", 8, true ), Parity, SerialConfig->GetChInt( "StopBits", 1, true ), FlowCtrl, SerialConfig->GetChInt( "DataWait", 0, true )); + Persitent = true; } } else if (!strcasecmp( Type, "LinePrinter" )) @@ -180,6 +182,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) Address = (char*)HandleConfig->GetChStr( "Port/Address", NULL, true ); // Get default value } SetLinePrinterHandle( Handle, Address ); + Persitent = true; } else if (!strcasecmp( Type, "UNIXserver" )) { @@ -190,6 +193,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } Queue = HandleConfig->GetChInt( "Socket/Queue", 2, true ); SetUnixHandle( Handle, ctUNIXserver, Address, Queue ); + Persitent = true; } else if (!strcasecmp( Type, "UNIXclient" )) { @@ -199,69 +203,75 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value } SetUnixHandle( Handle, ctUNIXclient, Address, 0 ); + Persitent = false; } else if (!strcasecmp( Type, "UDPserver" )) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value - Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value + Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value - Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value + Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value } SetSocketHandle( Handle, ctUDPserver, Address, strlcase(Port), 0 ); + Persitent = true; } else if (!strcasecmp( Type, "UDPclient" )) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value - Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value + Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value - Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value + Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value } SetSocketHandle( Handle, ctUDPclient, Address, strlcase(Port), 0 ); + Persitent = false; } else if (!strcasecmp( Type, "TCPserver" )) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value - Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value + Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value - Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value + Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value } Queue = HandleConfig->GetChInt( "Socket/Queue", 2, true ); SetSocketHandle( Handle, ctTCPserver, Address, strlcase(Port), Queue ); + Persitent = true; } else if (!strcasecmp( Type, "TCPclient" )) { if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value - Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value + Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value - Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value + Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value } SetSocketHandle( Handle, ctTCPclient, Address, strlcase(Port), 0 ); + Persitent = false; } else if (!strcasecmp( Type, "ForkPipe" )) { Address = (char*)HandleConfig->GetChStr( "Fork/ExecPath", NULL, true ); // Get default value SetForkPipeHandle( Handle, Address ); + Persitent = true; } // Set Auto Manage - SetAutoManage( Handle, HandleConfig->GetChBool( "AutoManage/Enabled", true, true ), - HandleConfig->GetChBool( "AutoManage/Persistent", false, true ), - HandleConfig->GetChInt( "AutoManage/ReopenDelay", 2000, true ), - HandleConfig->GetChInt( "AutoManage/CloseTimeout", 2000, true )); + SetAutoManage( Handle, HandleConfig->GetChBool( "AutoManage/Enabled", true, true ), + HandleConfig->GetChBool( "AutoManage/Persistent", Persitent, true ), + HandleConfig->GetChInt( "AutoManage/ReopenDelay", 2000, true ), + HandleConfig->GetChInt( "AutoManage/CloseTimeout", 2000, true )); // Input buffer - SetInBuffer( Handle, HandleConfig->GetChInt( "InputBuffer/Size", 0 ), - HandleConfig->GetChInt( "InputBuffer/Timeout", 250 ), - HandleConfig->GetChStr( "InputBuffer/Marker", "" ), - HandleConfig->GetChInt( "InputBuffer/MarkerLen", 0 ) ); - SetOutBuffer( Handle, HandleConfig->GetChInt( "OutputBuffer/Size", 0 ) ); + SetInBuffer( Handle, HandleConfig->GetChInt( "InputBuffer/Size", 0 ), + HandleConfig->GetChInt( "InputBuffer/Timeout", 250 ), + HandleConfig->GetChStr( "InputBuffer/Marker", "" ), + HandleConfig->GetChInt( "InputBuffer/MarkerLen", 0 ) ); + SetOutBuffer( Handle, HandleConfig->GetChInt( "OutputBuffer/Size", 0 ) ); // Next HandleConfig = HandleConfig->GetNextPeer(); @@ -2330,51 +2340,6 @@ int CSelectableCore::OutputHandle( THandle * Handle, const char * Data, int Len } //--------------------------------------------------------------------------- -bool CSelectableCore::Process() -{ - THandle * Handle = NULL; - - // Process all Handles - Handle = FirstHandle; - while (Handle) - { - // Auto manage handles - if (Handle->State == csPrepared) { - // Proceed to open - Open( Handle ); - } - else if ((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent) { - // Try to re-open port after delay - if (Timeout( Handle->LastAction, Handle->ReopenDelay )) { - Open( Handle ); - } - } - - // Check Input buffers - if (Handle->InBuffer && (Handle->InBuffer->Len() > 0)) { - // Check duration since last PortIn - if (Timeout( Handle->InStart, Handle->InTimeout )) { - // Process Input - ProcessInputBuffer( Handle, true ); - - // Reset timer - ClearStartTime( &(Handle->InStart) ); - } - } - - // Check for auto close (but not on servers) - if ((Handle->State == csOpen) && Handle->AutoManage && !Handle->Persistent && (Handle->Type != ctTCPserver) && (Handle->Type != ctUNIXserver)) { - // Close port after timeout - if (Timeout( Handle->LastAction, Handle->CloseTimeout )) { - Close( Handle, true ); - } - } - Handle = Handle->Next; - } - return true; -} -//--------------------------------------------------------------------------- - // Set serial port configuration parameters bool CSelectableCore::WriteSerialConfig( THandle * Handle ) { diff --git a/SelectableCore.h b/SelectableCore.h index 24d2d51..67a8207 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -365,7 +365,6 @@ public: // Function Interface virtual int OutputHandle( THandle * Handle, const char * Data, int Len ); - virtual bool Process(); friend void ResolveHandler( int Signal, siginfo_t * SignalInfo, void * Context ); };