//
//  Copyright © 2001 - 2004, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   Logger.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines the CLogger class and sundry helpers for the 6046 main work-horse.
//
//  Notes:
//

#if !defined(AFX_LOGGER_H__DD6BE1B3_B9A9_4031_BE42_67AD086127CF__INCLUDED_)
#define AFX_LOGGER_H__DD6BE1B3_B9A9_4031_BE42_67AD086127CF__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

///////////////////////////////////////////////////////////////////////////////
// Included header files.

#include "StartupCheck.h"
#include "Component.h"
#include "PLCConfiguration.h"
#include "SurveyEventLog.h"
#include "Alarm.h"
#include "Disk.h"
#include "SystemMonitor.h"
#include "Sensor.h"
#include "SensorScheduler.h"
#include "SecondaryHandling.h"
#include "TriggerController.h"
#include "GeneralScheduler.h"
#include "TimeEmitter.h"

#include "..\Utils\NetUtils\PLCSensorData.h"
#include "..\Utils\NetUtils\SystemTime.h"
#include "..\Utils\NetUtils\BufferedData.h"
#include "..\Utils\NetUtils\CriticalParameterTable.h"

// STL support.
// Note: Microsoft's STL implementation is dirty at warning level 4 et. al. so silence it,
// as necessary.

#pragma warning( disable : 4018 )
#pragma warning( disable : 4146 )
#pragma warning( push, 3 )
#include <string>                                                           // STL string support.
#include <list>                                                             // Linked list support.
#include <deque>                                                            // Double ended queue support.
#include <map>                                                              // Map support.
#pragma warning( pop )
#pragma warning( default : 4146 )
#pragma warning( default : 4018 )

///////////////////////////////////////////////////////////////////////////////
// Forward definitions.

class CClientConnections;

///////////////////////////////////////////////////////////////////////////////
// CLogger and related definitions.

///////////////////
// Constants.

const unsigned long g_ulMaxOptionsLength = 256UL;

///////////////////
// Macros.

#define USE_OPTIMAL_COMMAND_INDEXING
#define DEFINE_COMMAND_HANDLER( Handler )   bool    Handler (   char                            *pszOptions,    \
                                                                const int                       &riSocketIndex, \
                                                                const int                       &riSensorIndex, \
                                                                const unsigned long             &rulAction )

///////////////////
// CLogger class definition.

class CLogger : public CBaseThread
{
public:

    ///////////////
    // Definitions.

    typedef enum tagETHREADMESSAGES                                         // Recognised thread messages.
    {
        messageCommand          = threadMessageTerminate + 1,               // Command queued and is pending processing.
        messageStatus,                                                      // Sensor status change.
        messageData,                                                        // Sensor data available.
        messageShutdown,                                                    // Shutdown request from remote host.
        messageRouted7kRecord,                                              // Non-command 7k message queued for routing to sensor.
        messageAlarmStateChange,                                            // Alarm has either been triggered or cleared.
        messageKillClientConnection,                                        // Terminate a specified client connection by socket index.
        messageQuerySensorSettings                                          // Solicit a settings query for all sensors.
    }
    ETHREADMESSAGES;

    typedef void         ( *PFN_TERMINATE_CALLBACK )    (   void );

    ///////////////
    // Services.

                            CLogger                     (   PFN_TERMINATE_CALLBACK              pfnTerminate = NULL );
    virtual                ~CLogger                     (   void );

    bool                    IsInitialized               (   void ) const;

    bool                    QueueCommand                (   const unsigned long                &rulCommand,
                                                            const int                          &riSensorIndex,
                                                            const unsigned long                &rulAction,
                                                            LPCTSTR                             lpszOptions,
                                                            const   unsigned long              &rulTimeStamp,
                                                            const int                          &riSocketIndex );

    bool                    Queue7kMessageForRouting    (   const BYTE                         *pbyData,
                                                            const unsigned long                &rulNumBytes,
                                                            const unsigned long                &rulTimeStamp,
                                                            const int                          &riSocketIndex );

    bool                    DispatchToSubscribingClients(   const BYTE                         *pbyData,
                                                            const unsigned long                &rulSize,
                                                            const unsigned long                &rulTimestamp,
                                                            const int                          &riSensorIndex );

    static
    void                    SplitPath                   (   LPCTSTR                             lpszFullName,
                                                            CString                            &rPath,
                                                            CString                            &rFileName );

    static
    void                    MakePath                    (   CString                            &rFullName,
                                                            LPCTSTR                             lpszDrive,
                                                            LPCTSTR                             lpszPath,
                                                            LPCTSTR                             lpszFile,
                                                            LPCTSTR                             lpszExtension );

    static
    bool                    SetApplicationPath          (   CString                            &rAppPath );

private:

    ///////////////
    // Definitions.


    typedef enum tagETIMESYNCMODE
    {
        timesyncModeStandAlone              = 0,                            // Stand alone time sync mode.
        timesyncModeSlaved                                                  // Slaved mode, prohibits time sync messages.
    }
    ETIMESYNCMODE;


    class CCommandHandler
    {
    private:

        ///////////////
        // Definitions.

        typedef bool ( CLogger::*  PFN_COMMAND_HANDLER )    (   char                   *pszOptions,
                                                                const int              &riSocketIndex,
                                                                const int              &riSensorIndex,
                                                                const unsigned long    &rulAction );

#ifdef USE_OPTIMAL_COMMAND_INDEXING

        // Use std::vector<> to optimize performance.

        typedef std::vector<PFN_COMMAND_HANDLER>                                        HandlerMap_t;

#else

        // Later, we may want to use map<> internally to allow us to readily change the indexing schemes. For example,
        // we may want to reassign indexes or even use string indexing by changing the key to string. In the latter case,
        // use the following typedef:
        //
        // typedef std::map<string, PFN_COMMAND_HANDLER, less<string> >                 HandlerMap_t;

        typedef std::map<unsigned long, PFN_COMMAND_HANDLER>                            HandlerMap_t;

#endif

        typedef HandlerMap_t::iterator                                                  HandlerMapIterator_t;

        ///////////////
        // Attributes.

        HandlerMap_t                                                                    m_Map;
        CLogger                                                                        *m_pParent;

        ///////////////
        // Services.

                            CCommandHandler                 (   const CCommandHandler  &rRhs );         // Not implemented thus private.
        CCommandHandler &   operator =                      (   const CCommandHandler  &rRhs );         // Not implemented thus private.

    public:

        ///////////////
        // Services.

                            CCommandHandler                 (   void );
        virtual            ~CCommandHandler                 (   void );

        void                SetParent                       (   CLogger                *pParent );

        bool                operator ()                     (   const unsigned long    &rulCommand,
                                                                char                   *pszOptions,
                                                                const int              &riSocketIndex,
                                                                const int              &riSensorIndex,
                                                                const unsigned long    &rulAction      );
    };

#pragma pack( push, LOGGER_H_PACK, 1 )

    typedef struct tagMODULE
    {
        int                 m_iModuleNumber;
        int                 m_iMediaType;
        char                m_szFileName   [ _MAX_FNAME ];
        char                m_szModuleName [ _MAX_PATH  ];
    }
    MODULE;

#pragma pack( pop, LOGGER_H_PACK )

    class CModuleItem : public MODULE
    {
    private:

        const int           m_iInvalidModuleNumber;

    public:

        CComponent         *m_pComponent;

                            CModuleItem                     (   void );

                            CModuleItem                     (   const CModuleItem      &rRhs );

                            CModuleItem                     (   const MODULE           &rsModule,
                                                                CComponent             *pComponent = NULL );

        virtual            ~CModuleItem                     (   void );

        bool                operator <                      (   const CModuleItem      &rRhs )              const;

        bool                operator ==                     (   const int              &riModuleNumber )    const;

        bool                Load                            (   LPCTSTR lpszPath );

        bool                Unload                          (   void );
    };


    class CRunItem
    {
    public:

        int                 m_iModuleNumber;
        CSensor             m_Sensor;

                            CRunItem                        (   const int              &riModuleNumber = -1,
                                                                const SENSORINFO       *psSensorInfo   = NULL );

        virtual             ~CRunItem                       (   void );

        bool                operator <                      (   const CRunItem         &rRhs ) const;

        bool                operator ==                     (   const CRunItem         &rRhs ) const;

                            operator SENSORINFO *           (   void ) const;
    };


    class CQueuedCommand
    {
    private:

        int                 m_iSensorIndex;
        unsigned long       m_ulAction;
        unsigned long       m_ulTimeStamp;
        int                 m_iSocketIndex;
        unsigned long       m_ulCommand;
        char                m_szOptions[ g_ulMaxOptionsLength   ];

                            CQueuedCommand                  (   void );                                 // Not implemented so make private.
        void                Copy                            (   const CQueuedCommand   &rRhs );

    public:

                            CQueuedCommand                  (   const unsigned long    &rulCommand,
                                                                const int              &riSensorIndex,
                                                                const unsigned long    &rulAction,
                                                                LPCTSTR                 lpszOptions,
                                                                const unsigned long    &rulTimeStamp,
                                                                const int              &riSocketIndex );

                            CQueuedCommand                  (   const CQueuedCommand   &rRhs );

        virtual            ~CQueuedCommand                  (   void );

        CQueuedCommand &    operator =                      (   const CQueuedCommand   &rRhs );

        int                 SensorIndex                     (   void ) const;

        unsigned long       Command                         (   void ) const;

        char *              Options                         (   void ) const;

        unsigned long       Action                          (   void ) const;

        int                 SocketIndex                     (   void ) const;

                            operator unsigned long          (   void ) const;

    };


    class CQueued7kMessage : public tagQUEUEDMESSAGE
    {
    public:

        int                 m_iSocketIndex;

                            CQueued7kMessage                (   const unsigned long    &rulTimeStamp   = 0UL,
                                                                const int              &riSocketIndex  = 0 );

        virtual            ~CQueued7kMessage                (   void );
    };

    friend class                            CCommandHandler;                // Grant the command handler access to CLogger.

    typedef std::list<CModuleItem>          ModuleList_t;                   // DLL module list.
    typedef ModuleList_t::iterator          ModuleListIterator_t;

    typedef std::list<CRunItem>             RunList_t;                      // Sensor run list.
    typedef RunList_t::iterator             RunListIterator_t;
    typedef RunList_t::reverse_iterator     RunListReverseIterator_t;

    typedef std::deque<CQueuedCommand>      CommandQueue_t;                 // Command queue as received from remote clients.
    typedef CommandQueue_t::iterator        CommandQueueIterator_t;

    typedef CBufferedData<CQueued7kMessage> MessageQueue7k_t;               // Holding buffers for 7k messages to be routed to the appropriate sensor.

    typedef std::vector<MODULE>             KnownModules_t;                 // Known 6046 modules.
    typedef KnownModules_t::iterator        KnownModulesIterator_t;

    ///////////////
    // Attributes.

    const float                 m_fVersion;                                 // Payload controller version number.
    const unsigned long         m_ulMaxLogBufferSize;                       // Data handling buffer.
    const unsigned long         m_ulMaxMessageLength;                       // Max ethernet message size.
    const int                   m_iInvalidSensorIndex;                      // General invalid sensor index.
    const unsigned int          m_uiDefaultListenPort;                      // The default listener TCP/IP port.
    const unsigned long         m_ulDongleCheckPeriodInMilliseconds;        // Dongle check period in ms.
    const unsigned long         m_ulHostTimeNotificationPeriod;             // Period to initiate emmission of time records to host in ms.

    PFN_TERMINATE_CALLBACK      m_pfnTerminate;

    bool                        m_bInitialized;                             // Construction success flag.
    bool                        m_bActiveOnStart;                           // Flag indicating whether logging and active sensors are to go active when the PLC starts.

    BYTE                       *m_pby7kRecordBuffer;                        // Data logging buffer.

    int                         m_iShutdownMode;                            // 
    int                         m_iRoutingSensorIndex;                      // 

    unsigned int                m_uiListenPort;                             // Socket listening port for socket server... default is 6046 but maybe read from registry (key: "RemoteControlPort" ).
    unsigned long               m_ulRecordCounter;                          // Running record counter.
    unsigned long               m_ulSessionId;                              // User defined session id. For now, read from registry.
    unsigned long               m_ulNextSensorRecordToRead;                 // Next sensor record to read in the shared sensor memory pool.
    unsigned long               m_ulSensorCycleDongleCheck;                 // Cyclical counter to trigger dongle checking during data collection.
    unsigned long               m_ulDiskWriteFailCount;                     // 

    CString                     m_AppPath;                                  // Path for this application.
    CString                     m_UserNotes;                                // User notes as set in the registry.
    CString                     m_UserName;                                 // User name   "  "   "  "     "

    unsigned int                m_uiDataReadyMessageId;                     // Thread message id for data ready.
    unsigned int                m_uiReplyReadyMessageId;                    // Thread message id for sensor status change, alarm or general reply.

    ETIMESYNCMODE               m_eTimeSyncMode;                            // Time synchronization modes. See enum above.

    CCritical                   m_CriticalCommandQueue;                     // Critical section object to guard the command queue.

    mutable ModuleList_t        m_ModuleList;                               // List of detected modules (component DLLs) for different sensor types.
    mutable RunList_t           m_RunList;                                  // List of mapped and executable sensors and reference back to their module.
    mutable KnownModules_t      m_KnownModules;                             // List of known modules that can be loaded.
    mutable CCritical           m_CriticalRoutedMessageQueue;               // Critical section object to guard the routed message queue.

    CPLCConfiguration           m_Config;
    CommandQueue_t              m_CommandQueue;                             // Inbound queued command list to be handled by command handlers.
    CCommandHandler             m_CommandHandler;                           // Command handler object to invoke remote commands.
    MessageQueue7k_t            m_RoutingQueue;                             // 7k message queue to route to appropriate sensor.
    //CCriticalParameterTable     m_CriticalParameterTable;                   // Critical parameter object to permit sensors to subscribe and pulbish critical survey data (e.g., sound speed).
    CStartupCheck               m_StartupCheck;                             // Prelaunch check object used to do registry creation etc. before rest of internal objects below get constructed.
    CSystemTime                 m_SystemTime;                               // System time object.
    CSurveyEventLog             m_SurveyEventLog;                           // Survey event log object; also provides interface for reporting alarms (i.e., drive m_Alarm object too).
    CAlarm                      m_Alarm;                                    // Alarm monitor object.
    CSystemMonitor              m_SystemMonitor;                            // General system status and health monitoring object.
    CDisk                       m_DiskDataLog;                              // Disk data logging object.
    CSensorScheduler            m_SensorScheduler;                          // Scheduler of sensors with a deferred startup period.
    //CTriggerController          m_TriggerController;                        // Maintains the sensors to pulse repetition period mappings in order to update appropriate critical parameters.
    CGeneralScheduler           m_DongleCheckScheduler;                     // Dongle check scheduler.
    CTimeEmitter                m_TimeEmitter;                              // Self scheduling time message generator for subsequent host notification.

    CPLCReadSensorData         *m_pSensorData;                              // Shared sensor data pool access object.
    CClientConnections         *m_pClients;                                 // Socket representation of connected top-side clients.
    CSecondaryHandling         *m_pSecondaryHandler;                        // Threaded secondary data handler; queues data in a MMF for subsequent dispatch to subscribing clients, QC processing etc.

    ///////////////
    // Services.

    // General helpers.

    bool        InitializeThreadObjects         (   void );

    bool        TerminateThreadObjects          (   void );

    bool        CreateDataCollectionObjects     (   void );

    bool        DestroyDataCollectionObjects    (   void );

    bool        InitializeSensorDataPool        (   void );

    bool        LoadConfiguration               (   const LPCTSTR                   lpszPLCConfigFileName );

    bool        LoadModules                     (   void );

    bool        UnloadModules                   (   void );

    bool        IsRecognizedModule              (   const CString                   &FileName,
                                                    int                             &riIndex )          const;

    int         NextAvailableSensorIndex        (   void ) const;

    void        PrepareForShutdown              (   const int                       &riMode );

    void        Shutdown                        (   void )                                              const;

    bool        IsActivateOnStart               (   void )                                              const;

    bool        AutoStartMode                   (   const DWORD                     &rdwMode )          const;

    void        Set7kFileHeaderAttributesFromRegistry(  void );

    void        SetRoutingSensor                (   const int                      &riRoutingSensorIndex );

    bool        IsRoutingSensorSet              (   void ) const;

    int         RoutingSensorIndex              (   void ) const;

    void        RestoreMessageRoutingFromRegistry(  void );

    bool        Route7kMessagesToSensor         (   void );

    void        SetTimeSynchronizationMode      (   void );

    bool        ProcessAlarmMessage             (   const EALARMID                 &reAlarmId,
                                                    const int                      &riSecondaryIndex );

    void        ProcessEvents                   (   const HANDLE                   *phEventHandles,
                                                    const DWORD                    &rdwEventIndex );

    static
    bool        PerformSystemCheck              (   void                           *pvParam,
                                                    CString                        *pHealthMessage,
                                                    const bool                     &rbReportOnly    );

    bool        CheckHealthOfSensor             (   const int                      &riSensorIndex,
                                                    const bool                     &rbReportOnly );

    bool        CheckHealthOfSensor             (   CComponent * const              pComponent,
                                                    CSensor    * const              pSensor,
                                                    const bool                     &rbReportOnly );

    bool        ResetSensor                     (   const int                      &riSensorIndex );

    bool        HandleSimulateCommand           (   const CString                  &rCommand );

    bool        ParseAlarmCommandString         (   const CString                  &rCommand,
                                                    unsigned long                  &rulCommandIndex,
                                                    int                            &riAlarmIndex,
                                                    int                            &riActivation,
                                                    CString                        &rDescription );

    void        Adjust7kRecordHeader            (   const BYTE                     *pby7kRecord,
                                                    const unsigned long            &rulTotalRecordBytes,
                                                    const unsigned int             &riSensorIndex );

    // Module (component) and run list helpers.
    
    bool        ModuleFromRunListItem           (   const RunListIterator_t          pRunListItem,
                                                    ModuleListIterator_t            &rpModule )         const;

    bool        ComponentFromRunListItem        (   const RunListIterator_t          pRunListItem,
                                                    CComponent                   *  &rpComponent )      const;

    bool        ComponentFromRunList            (   const int                       &riSensorIndex,
                                                    CComponent                   *  &rpComponent );

    bool        SensorFromRunListItem           (   const RunListIterator_t          pRunListItem,
                                                    CSensor                      *  &rpSensor )         const;

    bool        SensorAndComponentFromIndex     (   const int                       &riSensorIndex,
                                                    CComponent                   *  &rpComponent,
                                                    CSensor                      *  &rpSensor    )      const;

    // Overloads to above for reverse iteration support.

    bool        ModuleFromRunListItem           (   const RunListReverseIterator_t  pRunListItem,
                                                    ModuleListIterator_t           &rpModule )          const;

    bool        ComponentFromRunListItem        (   const RunListReverseIterator_t  pRunListItem,
                                                    CComponent                   * &rpComponent )       const;

    bool        SensorFromRunListItem           (   const RunListReverseIterator_t  pRunListItem,
                                                    CSensor                      * &rpSensor )          const;

    // More runlist and sensor support.

    bool        BuildRunList                    (   void );

    bool        StartSensors                    (   void );

    bool        ShutdownRunListItems            (   void );

    void        StartDeferredSensorAndReschedule(   void );

    // Thread message and event processing handlers.

    bool        HandleSensorData                (   void );


    bool        ProcessStatusMessage            (   const int                       &riSensorIndex,
                                                    const int                       &riSocketIndex );

    bool        IsAlarmMessage                  (   const BYTE * const              pby7kRecord,
                                                    const unsigned long             &rulDataSize );

    void        HandleAlarmMessage              (   const BYTE * const              pby7kRecord,
                                                    const unsigned long             &rulDataSize,
                                                    unsigned long                   &rulTimeStamp,
                                                    const int                       &riSensorIndex );

    bool        ProcessQueuedCommands           (   void );

    // Miscellaneous helpers.

    bool        Record                          (   const bool                      &rbRecord,
                                                    LPCTSTR                          lpszPath     = NULL,
                                                    LPCTSTR                          lpszFileName = NULL );

    void        SetFileHeaderAndEnumerationInfo (   void );

    void        CheckAvailableDiskSpace         (   void );

    bool        IsValidPort                     (   const int                       &riPort     )       const;
    bool        IsValidSensorId                 (   const int                       &riSensorId )       const;
    bool        IsValidModuleId                 (   const int                       &riModuleId )       const;

    bool        AddAndStartSensor               (   const int                       &riModuleNumber,
                                                    const int                       &riPort,
                                                    const int                       &riSubsystemId,
                                                    const CString                   &rSensorName );

    bool        ShutdownAndRemoveSensor         (   const int                       &riSensorIndex );

    bool        PreProcessRouted7kMessage       (   const BYTE                      *pby7kRecord,
                                                    const unsigned long             &rulNumBytes,
                                                    const unsigned long             &rulTimeStamp );

    bool        ValidateDongle                  (   void );
    void        CheckDongleAndReschedule        (   void );

    void        EmitTimeToHostsAndReschedule    (   void );

    void        LoadKnownModuleList             (   void );
    bool        LoadModulesFromConfiguration    (   void );

    void        DumpRecordInfo                  (   const int                       &riSensorIndex,
                                                    const unsigned long             &rulNextSensorRecordToRead,
                                                    const BYTE * const               pby7kRecordBuffer,
                                                    const unsigned long             &ulTotalRecordBytes );

   // Command handler helpers.

    bool        ExecuteCommand                  (   const CQueuedCommand            &rCommand );
    bool        HandlePLCASCIICommand           (   const unsigned long             &rulAction,
                                                    const char                      *pszOptions );

    // Top-side client connection helpers.

    bool        EnableClientConnections         (   void );
    bool        DisableClientConnections        (   const bool                     &rbNotifyAllClients = true );
    bool        NotifyClientsOfTermination      (   void );

    bool        AcknowlegeCommand               (   const int                      &riSocketIndex,
                                                    const bool                     &rbSuccess,
                                                    const unsigned long            &rulCommandId,
                                                    const int                      &riSensorId,
                                                    const bool                     &rbForceSend         = false );

    bool        Reply                           (   const int                      &riSocketIndex,
                                                    const int                      &riMessageType,
                                                    const int                      &riMode,
                                                    const int                      &riMessageId,
                                                    LPCTSTR                        lpszFormat, ... );

    void        TerminateClientConnection       (   const int                      &riSocketIndex );

    void        QuerySensorSettings             (   void );

    // CBaseThread's virtual overrides.

    BOOL        ProcessMessage                  (   MSG                             *psMsg );
    void        WatchCycle                      (   void );

    // Default copy constructor and assignment operator not implemented so make private to ensure non-usage.

                CLogger                         (   const CLogger                   &rRhs );            // Not implemented thus private.
    CLogger &   operator =                      (   const CLogger                   &rRhs );            // Not implemented thus private.

    // Private command handlers for remote control.

    DEFINE_COMMAND_HANDLER( CommandGeneric         );
    DEFINE_COMMAND_HANDLER( CommandLogging         );
    DEFINE_COMMAND_HANDLER( CommandSwitch          );
    DEFINE_COMMAND_HANDLER( CommandPath            );
    DEFINE_COMMAND_HANDLER( CommandVersion         );
    DEFINE_COMMAND_HANDLER( CommandLoad            );
    DEFINE_COMMAND_HANDLER( CommandSave            );
    DEFINE_COMMAND_HANDLER( CommandSubscribe       );
    DEFINE_COMMAND_HANDLER( CommandUnsubscribe     );
    DEFINE_COMMAND_HANDLER( CommandAlarm           );
    DEFINE_COMMAND_HANDLER( CommandStatus          );
    DEFINE_COMMAND_HANDLER( CommandTime            );
    DEFINE_COMMAND_HANDLER( CommandVerbose         );
    DEFINE_COMMAND_HANDLER( CommandReset           );
    DEFINE_COMMAND_HANDLER( CommandShutdown        );
    DEFINE_COMMAND_HANDLER( CommandModules         );
    DEFINE_COMMAND_HANDLER( CommandRunList         );
    DEFINE_COMMAND_HANDLER( CommandAdd             );
    DEFINE_COMMAND_HANDLER( CommandRemove          );
    DEFINE_COMMAND_HANDLER( CommandReport          );
    DEFINE_COMMAND_HANDLER( CommandPort            );
    DEFINE_COMMAND_HANDLER( CommandTimeSync        );
    DEFINE_COMMAND_HANDLER( CommandHealth          );
    DEFINE_COMMAND_HANDLER( CommandAutoStart       );
    DEFINE_COMMAND_HANDLER( CommandAutoHealthCheck );
    DEFINE_COMMAND_HANDLER( CommandRouteMessages   );
    DEFINE_COMMAND_HANDLER( CommandReportAlarms    );
    DEFINE_COMMAND_HANDLER( CommandLoggingSetup    );
    DEFINE_COMMAND_HANDLER( CommandSimulate        );
    DEFINE_COMMAND_HANDLER( CommandTimeMessage     );
    DEFINE_COMMAND_HANDLER( CommandIsAlive         );

};

#endif // !defined(AFX_LOGGER_H__DD6BE1B3_B9A9_4031_BE42_67AD086127CF__INCLUDED_)
