|
UniSet
2.2.1
|
00001 // ----------------------------------------------------------------------------- 00002 #ifndef _MBSlave_H_ 00003 #define _MBSlave_H_ 00004 // ----------------------------------------------------------------------------- 00005 #include <ostream> 00006 #include <string> 00007 #include <memory> 00008 #include <map> 00009 #include <unordered_map> 00010 #include <vector> 00011 #include <condition_variable> 00012 #include <atomic> 00013 #include <mutex> 00014 #include "UniSetObject.h" 00015 #include "modbus/ModbusTypes.h" 00016 #include "modbus/ModbusServerSlot.h" 00017 #include "PassiveTimer.h" 00018 #include "Trigger.h" 00019 #include "Mutex.h" 00020 #include "SMInterface.h" 00021 #include "SharedMemory.h" 00022 #include "IOBase.h" 00023 #include "VTypes.h" 00024 #include "ThreadCreator.h" 00025 #include "LogServer.h" 00026 #include "LogAgregator.h" 00027 #include "VMonitor.h" 00028 // ----------------------------------------------------------------------------- 00029 #ifndef vmonit 00030 #define vmonit( var ) vmon.add( #var, var ) 00031 #endif 00032 // ----------------------------------------------------------------------------- 00276 // ----------------------------------------------------------------------------- 00277 namespace std 00278 { 00279 template<> 00280 class hash<ModbusRTU::mbErrCode> 00281 { 00282 public: 00283 size_t operator()(const ModbusRTU::mbErrCode& e) const 00284 { 00285 return std::hash<int>()((int)e); 00286 } 00287 }; 00288 } 00289 // ----------------------------------------------------------------------------- 00291 class MBSlave: 00292 public UniSetObject 00293 { 00294 public: 00295 MBSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "mbs" ); 00296 virtual ~MBSlave(); 00297 00299 static std::shared_ptr<MBSlave> init_mbslave(int argc, const char* const* argv, 00300 UniSetTypes::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr, 00301 const std::string& prefix = "mbs" ); 00302 00304 static void help_print( int argc, const char* const* argv ); 00305 00306 static const int NoSafetyState = -1; 00307 00308 enum AccessMode 00309 { 00310 amRW, 00311 amRO, 00312 amWO 00313 }; 00314 00315 struct BitRegProperty; 00316 00317 struct IOProperty: 00318 public IOBase 00319 { 00320 ModbusRTU::ModbusData mbreg; 00321 AccessMode amode; 00322 VTypes::VType vtype; 00323 int wnum; 00324 int nbyte; 00325 bool rawdata; 00326 std::shared_ptr<BitRegProperty> bitreg; 00327 ModbusRTU::RegID regID; 00328 00329 IOProperty(): 00330 mbreg(0), 00331 amode(amRW), 00332 vtype(VTypes::vtUnknown), 00333 wnum(0), 00334 nbyte(0), 00335 rawdata(false), 00336 regID(0) 00337 {} 00338 00339 friend std::ostream& operator<<( std::ostream& os, IOProperty& p ); 00340 }; 00341 00342 00343 struct BitRegProperty 00344 { 00345 typedef std::vector<IOProperty> BitSensorMap; 00346 00347 ModbusRTU::ModbusData mbreg; 00348 BitSensorMap bvec; 00349 00350 BitRegProperty(): mbreg(0), bvec(ModbusRTU::BitsPerData) {} 00351 00353 bool check( const IOController_i::SensorInfo& si ); 00354 00355 friend std::ostream& operator<<( std::ostream& os, BitRegProperty& p ); 00356 friend std::ostream& operator<<( std::ostream& os, BitRegProperty* p ); 00357 }; 00358 00359 inline long getAskCount() 00360 { 00361 return askCount; 00362 } 00363 00364 inline std::shared_ptr<LogAgregator> getLogAggregator() 00365 { 00366 return loga; 00367 } 00368 inline std::shared_ptr<DebugStream> log() 00369 { 00370 return mblog; 00371 } 00372 00373 virtual UniSetTypes::SimpleInfo* getInfo( CORBA::Long userparam = 0 ) override; 00374 00375 protected: 00376 00378 ModbusRTU::mbErrCode readCoilStatus( ModbusRTU::ReadCoilMessage& query, 00379 ModbusRTU::ReadCoilRetMessage& reply ); 00381 ModbusRTU::mbErrCode readInputStatus( ModbusRTU::ReadInputStatusMessage& query, 00382 ModbusRTU::ReadInputStatusRetMessage& reply ); 00383 00385 ModbusRTU::mbErrCode readOutputRegisters( ModbusRTU::ReadOutputMessage& query, 00386 ModbusRTU::ReadOutputRetMessage& reply ); 00387 00389 ModbusRTU::mbErrCode readInputRegisters( ModbusRTU::ReadInputMessage& query, 00390 ModbusRTU::ReadInputRetMessage& reply ); 00391 00393 ModbusRTU::mbErrCode forceSingleCoil( ModbusRTU::ForceSingleCoilMessage& query, 00394 ModbusRTU::ForceSingleCoilRetMessage& reply ); 00395 00397 ModbusRTU::mbErrCode forceMultipleCoils( ModbusRTU::ForceCoilsMessage& query, 00398 ModbusRTU::ForceCoilsRetMessage& reply ); 00399 00400 00402 ModbusRTU::mbErrCode writeOutputRegisters( ModbusRTU::WriteOutputMessage& query, 00403 ModbusRTU::WriteOutputRetMessage& reply ); 00404 00406 ModbusRTU::mbErrCode writeOutputSingleRegister( ModbusRTU::WriteSingleOutputMessage& query, 00407 ModbusRTU::WriteSingleOutputRetMessage& reply ); 00408 00410 // ModbusRTU::mbErrCode journalCommand( ModbusRTU::JournalCommandMessage& query, 00411 // ModbusRTU::JournalCommandRetMessage& reply ); 00412 00414 ModbusRTU::mbErrCode setDateTime( ModbusRTU::SetDateTimeMessage& query, 00415 ModbusRTU::SetDateTimeRetMessage& reply ); 00416 00418 ModbusRTU::mbErrCode remoteService( ModbusRTU::RemoteServiceMessage& query, 00419 ModbusRTU::RemoteServiceRetMessage& reply ); 00420 00421 ModbusRTU::mbErrCode fileTransfer( ModbusRTU::FileTransferMessage& query, 00422 ModbusRTU::FileTransferRetMessage& reply ); 00423 00424 ModbusRTU::mbErrCode diagnostics( ModbusRTU::DiagnosticMessage& query, 00425 ModbusRTU::DiagnosticRetMessage& reply ); 00426 00427 ModbusRTU::mbErrCode read4314( ModbusRTU::MEIMessageRDI& query, 00428 ModbusRTU::MEIMessageRetRDI& reply ); 00429 00433 virtual ModbusRTU::mbErrCode checkRegister( ModbusRTU::ModbusData reg, ModbusRTU::ModbusData& val ) 00434 { 00435 return ModbusRTU::erNoError; 00436 } 00437 00438 // т.к. в функциях (much_real_read,nuch_real_write) рассчёт на отсортированность IOMap 00439 // то использовать unordered_map нельзя 00440 typedef std::map<ModbusRTU::RegID, IOProperty> RegMap; 00441 00442 typedef std::unordered_map<ModbusRTU::ModbusAddr, RegMap> IOMap; 00443 00444 IOMap iomap; 00446 std::shared_ptr<ModbusServerSlot> mbslot; 00447 std::unordered_set<ModbusRTU::ModbusAddr> vaddr; 00448 std::string default_mbaddr = { "" }; 00449 00450 xmlNode* cnode = { 0 }; 00451 std::string s_field = { "" }; 00452 std::string s_fvalue = { "" }; 00453 int default_mbfunc = {0}; // функция по умолчанию, для вычисления RegID 00454 00455 std::shared_ptr<SMInterface> shm; 00456 00457 virtual void sysCommand( const UniSetTypes::SystemMessage* msg ) override; 00458 virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ) override; 00459 void askSensors( UniversalIO::UIOCommand cmd ); 00460 void waitSMReady(); 00461 virtual void execute_rtu(); 00462 virtual void execute_tcp(); 00463 00464 virtual bool activateObject() override; 00465 virtual bool deactivateObject() override; 00466 00467 // действия при завершении работы 00468 virtual void sigterm( int signo ) override; 00469 virtual void finalThread(); 00470 00471 virtual void initIterators(); 00472 bool initItem( UniXML::iterator& it ); 00473 bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec ); 00474 00475 void readConfiguration(); 00476 bool check_item( UniXML::iterator& it ); 00477 00478 ModbusRTU::mbErrCode real_write( RegMap& rmap, const ModbusRTU::ModbusData regOKOK, ModbusRTU::ModbusData val, const int fn = 0 ); 00479 ModbusRTU::mbErrCode real_write( RegMap& rmap, const ModbusRTU::ModbusData regOKOK, ModbusRTU::ModbusData* dat, int& i, int count, const int fn = 0 ); 00480 ModbusRTU::mbErrCode real_read( RegMap& rmap, const ModbusRTU::ModbusData regOKOK, ModbusRTU::ModbusData& val, const int fn = 0 ); 00481 ModbusRTU::mbErrCode much_real_read( RegMap& rmap, const ModbusRTU::ModbusData regOKOK, ModbusRTU::ModbusData* dat, int count, const int fn = 0 ); 00482 ModbusRTU::mbErrCode much_real_write( RegMap& rmap, const ModbusRTU::ModbusData regOKOK, ModbusRTU::ModbusData* dat, int count, const int fn = 0 ); 00483 00484 ModbusRTU::mbErrCode real_read_it( RegMap& rmap, RegMap::iterator& it, ModbusRTU::ModbusData& val ); 00485 ModbusRTU::mbErrCode real_bitreg_read_it( std::shared_ptr<BitRegProperty>& bp, ModbusRTU::ModbusData& val ); 00486 ModbusRTU::mbErrCode real_read_prop( IOProperty* p, ModbusRTU::ModbusData& val ); 00487 00488 ModbusRTU::mbErrCode real_write_it(RegMap& rmap, RegMap::iterator& it, ModbusRTU::ModbusData* dat, int& i, int count ); 00489 ModbusRTU::mbErrCode real_bitreg_write_it( std::shared_ptr<BitRegProperty>& bp, const ModbusRTU::ModbusData val ); 00490 ModbusRTU::mbErrCode real_write_prop( IOProperty* p, ModbusRTU::ModbusData* dat, int& i, int count ); 00491 00492 MBSlave(); 00493 timeout_t initPause = { 3000 }; 00494 UniSetTypes::uniset_rwmutex mutex_start; 00495 std::shared_ptr< ThreadCreator<MBSlave> > thr; 00496 00497 std::mutex mutexStartNotify; 00498 std::condition_variable startNotifyEvent; 00499 00500 PassiveTimer ptHeartBeat; 00501 UniSetTypes::ObjectId sidHeartBeat = { UniSetTypes::DefaultObjectId }; 00502 int maxHeartBeat = { 10 }; 00503 IOController::IOStateList::iterator itHeartBeat; 00504 UniSetTypes::ObjectId test_id = { UniSetTypes::DefaultObjectId }; 00505 00506 IOController::IOStateList::iterator itAskCount; 00507 UniSetTypes::ObjectId askcount_id = { UniSetTypes::DefaultObjectId }; 00508 00509 IOController::IOStateList::iterator itRespond; 00510 UniSetTypes::ObjectId respond_id = { UniSetTypes::DefaultObjectId }; 00511 bool respond_invert = { false }; 00512 00513 PassiveTimer ptTimeout; 00514 long askCount = { 0 }; 00515 typedef std::unordered_map<ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap; 00516 ExchangeErrorMap errmap; 00518 std::atomic_bool activated = { false }; 00519 std::atomic_bool cancelled = { false }; 00520 int activateTimeout = { 20000 }; // msec 00521 bool pingOK = { false }; 00522 timeout_t wait_msec = { 3000 }; 00523 bool force = { false }; 00525 bool mbregFromID = {0}; 00526 bool checkMBFunc = {0}; 00527 bool noMBFuncOptimize = {0}; // флаг отключающий принудительное преобразование функций (0x06->0x10, 0x05->0x0F) см. initItem() 00528 00529 int getOptimizeWriteFunction( const int fn ); // функция возвращает оптимизированную функцию (если оптимизация включена) 00530 00531 typedef std::unordered_map<int, std::string> FileList; 00532 FileList flist; 00533 std::string prefix = { "" }; 00534 std::string prop_prefix = { "" }; 00535 00536 ModbusRTU::ModbusData buf[ModbusRTU::MAXLENPACKET / 2 + 1]; 00538 // данные для ответа на запрос 0x2B(43)/0x0E(14) 00539 // 'MEI' - modbus encapsulated interface 00540 // 'RDI' - read device identification 00541 typedef std::unordered_map<int, std::string> MEIValMap; 00542 typedef std::unordered_map<int, MEIValMap> MEIObjIDMap; 00543 typedef std::unordered_map<int, MEIObjIDMap> MEIDevIDMap; 00544 00545 MEIDevIDMap meidev; 00546 00547 std::shared_ptr<LogAgregator> loga; 00548 std::shared_ptr<DebugStream> mblog; 00549 std::shared_ptr<LogServer> logserv; 00550 std::string logserv_host = {""}; 00551 int logserv_port = {0}; 00552 VMonitor vmon; 00553 }; 00554 // ----------------------------------------------------------------------------- 00555 #endif // _MBSlave_H_ 00556 // -----------------------------------------------------------------------------
1.7.6.1