UniSet  2.6.0
ModbusTCPSession.h
00001 // -------------------------------------------------------------------------
00002 #ifndef ModbusTCPSession_H_
00003 #define ModbusTCPSession_H_
00004 // -------------------------------------------------------------------------
00005 #include <string>
00006 #include <queue>
00007 #include <unordered_map>
00008 #include <ev++.h>
00009 #include "ModbusServerSlot.h"
00010 #include "ModbusServer.h"
00011 #include "PassiveTimer.h"
00012 #include "UTCPCore.h"
00013 #include "UTCPStream.h"
00014 // -------------------------------------------------------------------------
00015 namespace uniset
00016 {
00017 // -------------------------------------------------------------------------
00033 class ModbusTCPSession:
00034     public ModbusServerSlot,
00035     public ModbusServer
00036 {
00037     public:
00038 
00039         ModbusTCPSession( const Poco::Net::StreamSocket& s, const std::unordered_set<ModbusRTU::ModbusAddr>& vmbaddr, timeout_t timeout );
00040         virtual ~ModbusTCPSession();
00041 
00042         void cleanInputStream();
00043 
00044         virtual void cleanupChannel() override;
00045         virtual void terminate() override;
00046 
00047         typedef sigc::slot<void, const ModbusTCPSession*> FinalSlot;
00048 
00049         void connectFinalSession( FinalSlot sl );
00050 
00051         inline std::string getClientAddress() const
00052         {
00053             return caddr;
00054         }
00055 
00056         void setSessionTimeout( double t );
00057 
00058         // запуск обработки входящих запросов
00059         void run( ev::loop_ref& loop );
00060 
00061         virtual bool isActive() const override;
00062 
00063         void iowait( timeout_t msec );
00064 
00065     protected:
00066 
00067         virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vmbaddr, timeout_t msecTimeout ) override;
00068 
00069         void callback( ev::io& watcher, int revents );
00070         void onTimeout( ev::timer& watcher, int revents );
00071         virtual void readEvent( ev::io& watcher );
00072         virtual void writeEvent( ev::io& watcher );
00073         virtual void final();
00074 
00075         virtual size_t getNextData( unsigned char* buf, int len ) override;
00076         virtual void setChannelTimeout( timeout_t msec );
00077         virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) override;
00078         virtual ModbusRTU::mbErrCode tcp_processing( ModbusRTU::ADUHeader& mhead );
00079         virtual ModbusRTU::mbErrCode make_adu_header( ModbusRTU::ModbusMessage& request ) override;
00080         virtual ModbusRTU::mbErrCode post_send_request(ModbusRTU::ModbusMessage& request ) override;
00081 
00082         virtual ModbusRTU::mbErrCode readCoilStatus( ModbusRTU::ReadCoilMessage& query,
00083                                                      ModbusRTU::ReadCoilRetMessage& reply );
00084 
00085         virtual ModbusRTU::mbErrCode readInputStatus( ModbusRTU::ReadInputStatusMessage& query,
00086                                                       ModbusRTU::ReadInputStatusRetMessage& reply );
00087 
00088         virtual ModbusRTU::mbErrCode readOutputRegisters( ModbusRTU::ReadOutputMessage& query,
00089                                                           ModbusRTU::ReadOutputRetMessage& reply );
00090 
00091         virtual ModbusRTU::mbErrCode readInputRegisters( ModbusRTU::ReadInputMessage& query,
00092                                                          ModbusRTU::ReadInputRetMessage& reply );
00093 
00094         virtual ModbusRTU::mbErrCode forceSingleCoil( ModbusRTU::ForceSingleCoilMessage& query,
00095                                                       ModbusRTU::ForceSingleCoilRetMessage& reply );
00096 
00097         virtual ModbusRTU::mbErrCode writeOutputSingleRegister( ModbusRTU::WriteSingleOutputMessage& query,
00098                 ModbusRTU::WriteSingleOutputRetMessage& reply );
00099 
00100         virtual ModbusRTU::mbErrCode forceMultipleCoils( ModbusRTU::ForceCoilsMessage& query,
00101                                                          ModbusRTU::ForceCoilsRetMessage& reply );
00102 
00103         virtual ModbusRTU::mbErrCode writeOutputRegisters( ModbusRTU::WriteOutputMessage& query,
00104                 ModbusRTU::WriteOutputRetMessage& reply );
00105 
00106         virtual ModbusRTU::mbErrCode diagnostics( ModbusRTU::DiagnosticMessage& query,
00107                                                   ModbusRTU::DiagnosticRetMessage& reply );
00108 
00109         virtual ModbusRTU::mbErrCode read4314( ModbusRTU::MEIMessageRDI& query,
00110                                                ModbusRTU::MEIMessageRetRDI& reply );
00111 
00112         virtual ModbusRTU::mbErrCode journalCommand( ModbusRTU::JournalCommandMessage& query,
00113                                                      ModbusRTU::JournalCommandRetMessage& reply );
00114 
00115         virtual ModbusRTU::mbErrCode setDateTime( ModbusRTU::SetDateTimeMessage& query,
00116                                                   ModbusRTU::SetDateTimeRetMessage& reply );
00117 
00118         virtual ModbusRTU::mbErrCode remoteService( ModbusRTU::RemoteServiceMessage& query,
00119                                                     ModbusRTU::RemoteServiceRetMessage& reply );
00120 
00121         virtual ModbusRTU::mbErrCode fileTransfer( ModbusRTU::FileTransferMessage& query,
00122                                                    ModbusRTU::FileTransferRetMessage& reply );
00123 
00124     private:
00125         std::queue<unsigned char> qrecv;
00126         std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
00127         ModbusRTU::ADUHeader curQueryHeader;
00128         PassiveTimer ptTimeout;
00129         timeout_t timeout = { 0 };
00130         ModbusRTU::ModbusMessage buf;
00131 
00132         ev::io  io;
00133         ev::timer ioTimeout;
00134 
00135         std::shared_ptr<UTCPStream> sock;
00136         std::queue<UTCPCore::Buffer*> qsend;
00137         double sessTimeout = { 10.0 };
00138 
00139         bool ignoreAddr = { false };
00140         std::string peername = { "" };
00141 
00142         std::string caddr = { "" };
00143 
00144         FinalSlot slFin;
00145 
00146         std::atomic_bool cancelled = { false };
00147         PassiveTimer pt;
00148         PassiveTimer ptWait;
00149 };
00150 // -------------------------------------------------------------------------
00151 } // end of namespace uniset
00152 // -------------------------------------------------------------------------
00153 #endif // ModbusTCPSession_H_
00154 // -------------------------------------------------------------------------