UniSet  2.6.0
ModbusServer.h
00001 // -------------------------------------------------------------------------
00002 #ifndef ModbusServer_H_
00003 #define ModbusServer_H_
00004 // -------------------------------------------------------------------------
00005 #include <string>
00006 #include <unordered_set>
00007 #include <unordered_map>
00008 #include <sigc++/sigc++.h>
00009 
00010 #include "Debug.h"
00011 #include "Mutex.h"
00012 #include "Configuration.h"
00013 #include "PassiveTimer.h"
00014 #include "ModbusTypes.h"
00015 // -------------------------------------------------------------------------
00016 namespace std
00017 {
00018 template<>
00019 class hash<uniset::ModbusRTU::mbErrCode>
00020 {
00021     public:
00022         size_t operator()(const uniset::ModbusRTU::mbErrCode& e) const
00023         {
00024             return std::hash<size_t>()(e);
00025         }
00026 };
00027 }
00028 // -------------------------------------------------------------------------
00029 namespace uniset
00030 {
00031 // -------------------------------------------------------------------------
00033 class ModbusServer
00034 {
00035     public:
00036         ModbusServer();
00037         virtual ~ModbusServer();
00038 
00039         void initLog( uniset::Configuration* conf, const std::string& name, const std::string& logfile = "" );
00040         void setLog( std::shared_ptr<DebugStream> dlog );
00041         inline std::shared_ptr<DebugStream> log()
00042         {
00043             return dlog;
00044         }
00045 
00046         static std::unordered_set<ModbusRTU::ModbusAddr> addr2vaddr( ModbusRTU::ModbusAddr& mbaddr );
00047 
00053         ModbusRTU::mbErrCode receive( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, timeout_t msecTimeout );
00054 
00055         // версия с "одним" адресом
00056         virtual ModbusRTU::mbErrCode receive_one( const ModbusRTU::ModbusAddr addr, timeout_t msec );
00057 
00058 
00059         // ---------------------------------------------------------------------------------------
00060         // сигналы по обработке событий приёма сообщения.
00061         // ---------------------------------------------------------------------------------------
00062         // сигнал вызова receive, ДО обработки realReceive()
00063         // \return ModbusRTU::errNoError, тогда обработка продолжиться.
00064         typedef sigc::signal<ModbusRTU::mbErrCode, const std::unordered_set<ModbusRTU::ModbusAddr>, timeout_t> PreReceiveSignal;
00065         PreReceiveSignal signal_pre_receive();
00066 
00067         // сигнал после обработки realReceive()
00068         typedef sigc::signal<void, ModbusRTU::mbErrCode> PostReceiveSignal;
00069         PostReceiveSignal signal_post_receive();
00070         // ---------------------------------------------------------------------------------------
00071 
00078         static bool checkAddr( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, const ModbusRTU::ModbusAddr addr );
00079         static std::string vaddr2str( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr );
00080 
00084         timeout_t setAfterSendPause( timeout_t msec );
00085 
00089         timeout_t setReplyTimeout( timeout_t msec );
00090 
00092         void setRecvTimeout( timeout_t msec );
00093 
00095         inline void setSleepPause( timeout_t msec )
00096         {
00097             sleepPause_msec = msec;
00098         }
00099 
00100         inline void setCRCNoCheckit( bool set )
00101         {
00102             crcNoCheckit = set;
00103         }
00104         inline bool isCRCNoCheckit() const
00105         {
00106             return crcNoCheckit;
00107         }
00108 
00109         inline void setBroadcastMode( bool set )
00110         {
00111             onBroadcast = set;
00112         }
00113         inline bool getBroadcastMode() const
00114         {
00115             return onBroadcast;
00116         }
00117 
00118         inline void setCleanBeforeSend( bool set )
00119         {
00120             cleanBeforeSend = set;
00121         }
00122         inline bool getCleanBeforeSend()
00123         {
00124             return cleanBeforeSend;
00125         }
00126 
00130         static ModbusRTU::mbErrCode replySetDateTime( ModbusRTU::SetDateTimeMessage& query,
00131                                                       ModbusRTU::SetDateTimeRetMessage& reply,
00132                                                       std::shared_ptr<DebugStream> dlog = nullptr );
00133 
00134 
00140         static ModbusRTU::mbErrCode replyFileTransfer( const std::string& fname,
00141                                                        ModbusRTU::FileTransferMessage& query,
00142                                                        ModbusRTU::FileTransferRetMessage& reply,
00143                                                        std::shared_ptr<DebugStream> dlog = nullptr );
00144 
00145         virtual void cleanupChannel() {}
00146         virtual void terminate() {}
00147 
00148         virtual bool isActive() const = 0;
00149 
00150         // ------------ Статистика ---------------
00151         typedef std::unordered_map<ModbusRTU::mbErrCode, size_t> ExchangeErrorMap;
00152 
00153         ExchangeErrorMap getErrorMap();
00154         size_t getErrCount( ModbusRTU::mbErrCode e );
00155         size_t resetErrCount( ModbusRTU::mbErrCode e, size_t set = 0 );
00156 
00157         inline size_t getAskCount() const
00158         {
00159             return askCount;
00160         }
00161         void resetAskCounter();
00162 
00163     protected:
00164 
00165         virtual void iowait( timeout_t usec );
00166 
00167 
00169         virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, timeout_t msecTimeout ) = 0;
00170 
00176         virtual ModbusRTU::mbErrCode readCoilStatus( ModbusRTU::ReadCoilMessage& query,
00177                                                      ModbusRTU::ReadCoilRetMessage& reply ) = 0;
00183         virtual ModbusRTU::mbErrCode readInputStatus( ModbusRTU::ReadInputStatusMessage& query,
00184                                                       ModbusRTU::ReadInputStatusRetMessage& reply ) = 0;
00185 
00191         virtual ModbusRTU::mbErrCode readOutputRegisters( ModbusRTU::ReadOutputMessage& query,
00192                                                           ModbusRTU::ReadOutputRetMessage& reply ) = 0;
00193 
00199         virtual ModbusRTU::mbErrCode readInputRegisters( ModbusRTU::ReadInputMessage& query,
00200                                                          ModbusRTU::ReadInputRetMessage& reply ) = 0;
00201 
00207         virtual ModbusRTU::mbErrCode forceSingleCoil( ModbusRTU::ForceSingleCoilMessage& query,
00208                                                       ModbusRTU::ForceSingleCoilRetMessage& reply ) = 0;
00209 
00210 
00216         virtual ModbusRTU::mbErrCode writeOutputSingleRegister( ModbusRTU::WriteSingleOutputMessage& query,
00217                 ModbusRTU::WriteSingleOutputRetMessage& reply ) = 0;
00218 
00224         virtual ModbusRTU::mbErrCode forceMultipleCoils( ModbusRTU::ForceCoilsMessage& query,
00225                                                          ModbusRTU::ForceCoilsRetMessage& reply ) = 0;
00226 
00232         virtual ModbusRTU::mbErrCode writeOutputRegisters( ModbusRTU::WriteOutputMessage& query,
00233                 ModbusRTU::WriteOutputRetMessage& reply ) = 0;
00234 
00235 
00241         virtual ModbusRTU::mbErrCode diagnostics( ModbusRTU::DiagnosticMessage& query,
00242                                                   ModbusRTU::DiagnosticRetMessage& reply ) = 0;
00243 
00249         virtual ModbusRTU::mbErrCode read4314( ModbusRTU::MEIMessageRDI& query,
00250                                                ModbusRTU::MEIMessageRetRDI& reply ) = 0;
00251 
00252 
00258         virtual ModbusRTU::mbErrCode journalCommand( ModbusRTU::JournalCommandMessage& query,
00259                                                      ModbusRTU::JournalCommandRetMessage& reply ) = 0;
00260 
00261 
00267         virtual ModbusRTU::mbErrCode setDateTime( ModbusRTU::SetDateTimeMessage& query,
00268                                                   ModbusRTU::SetDateTimeRetMessage& reply ) = 0;
00269 
00270 
00276         virtual ModbusRTU::mbErrCode remoteService( ModbusRTU::RemoteServiceMessage& query,
00277                                                     ModbusRTU::RemoteServiceRetMessage& reply ) = 0;
00278 
00279 
00285         virtual ModbusRTU::mbErrCode fileTransfer( ModbusRTU::FileTransferMessage& query,
00286                                                    ModbusRTU::FileTransferRetMessage& reply ) = 0;
00287 
00294         virtual size_t getNextData( unsigned char* buf, int len ) = 0;
00295 
00296         virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) = 0;
00297 
00299         virtual void setChannelTimeout( timeout_t msec ) = 0;
00300 
00302         virtual ModbusRTU::mbErrCode send( ModbusRTU::ModbusMessage& buf );
00303 
00304         // Если заголовок не должен использоваться оставляйте request.header.len = 0
00305         virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request )
00306         {
00307             return ModbusRTU::erNoError;
00308         }
00309         virtual ModbusRTU::mbErrCode post_send_request( ModbusRTU::ModbusMessage& request )
00310         {
00311             return ModbusRTU::erNoError;
00312         }
00313 
00314         // default processing
00315         virtual ModbusRTU::mbErrCode processing( ModbusRTU::ModbusMessage& buf );
00316 
00318         ModbusRTU::mbErrCode recv(const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, ModbusRTU::ModbusMessage& buf, timeout_t timeout );
00319         ModbusRTU::mbErrCode recv_pdu( ModbusRTU::ModbusMessage& rbuf, timeout_t timeout );
00320 
00321         std::timed_mutex recvMutex;
00322         timeout_t recvTimeOut_ms = { 50 };        
00323         timeout_t replyTimeout_ms = { 2000 };    
00324         timeout_t aftersend_msec = { 0 };        
00325         timeout_t sleepPause_msec = { 10 };     
00326         bool onBroadcast = { false };        
00327         bool crcNoCheckit = { false };
00328         bool cleanBeforeSend = { false };
00329 
00330         void printProcessingTime();
00331         PassiveTimer tmProcessing;
00332 
00333         std::shared_ptr<DebugStream> dlog;
00334 
00335         // статистика сервера
00336         size_t askCount = { 0 };
00337         ExchangeErrorMap errmap;     
00339         PreReceiveSignal m_pre_signal;
00340         PostReceiveSignal m_post_signal;
00341 
00342     private:
00343 
00344 };
00345 // -------------------------------------------------------------------------
00346 } // end of namespace uniset
00347 // -------------------------------------------------------------------------
00348 #endif // ModbusServer_H_
00349 // -------------------------------------------------------------------------