|
UniSet
2.6.0
|
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 // -------------------------------------------------------------------------
1.7.6.1