Commit bd40cff6 authored by Pavel Vainerman's avatar Pavel Vainerman

Merge branch 'master' into devel/unet-priority

Conflicts: conf/libuniset2.spec extensions/UNetUDP/UNetReceiver.cc
parents bec1e9ef c1064d45
...@@ -32,9 +32,11 @@ Version 2.0 ...@@ -32,9 +32,11 @@ Version 2.0
- uniset-codegen: дописать функцию help со всеми параметрами для _SK, тесты - uniset-codegen: дописать функцию help со всеми параметрами для _SK, тесты
- uniset-codegen: добавить в генерируемую документацию значения по умолчанию.. - uniset-codegen: добавить в генерируемую документацию значения по умолчанию..
- uniset-codegen: добавить возможность переопределять привязку из командной строки
- unetudp: добавить возмоность привязать номера текущего посылаемого и принимаемого пакетов к датчику - unetudp: добавить возмоность привязать номера текущего посылаемого и принимаемого пакетов к датчику
- ModbusMaster: встроить возможность задать 'pulsar' (регистр сердцебиения)
- ТЕСТЫ! ТЕСТЫ! ТЕСТЫ! - ТЕСТЫ! ТЕСТЫ! ТЕСТЫ!
...@@ -42,6 +44,8 @@ Version 2.0 ...@@ -42,6 +44,8 @@ Version 2.0
uniset-codegen: добавить ключ --gen-sensor-name для генерирования name_Item.. (чтобы можно было в логах использовать текстовые названия) uniset-codegen: добавить ключ --gen-sensor-name для генерирования name_Item.. (чтобы можно было в логах использовать текстовые названия)
SQL: SQL:
==== ====
- добавить работу с History (при передаче указателя на SM в конструкторе). - добавить работу с History (при передаче указателя на SM в конструкторе).
......
...@@ -539,6 +539,7 @@ int omap() ...@@ -539,6 +539,7 @@ int omap()
{ {
if( !quiet ) if( !quiet )
cerr << "std::exception: " << ex.what() << endl; cerr << "std::exception: " << ex.what() << endl;
return 1; return 1;
} }
...@@ -600,6 +601,7 @@ int setValue( const string& args, UInterface& ui ) ...@@ -600,6 +601,7 @@ int setValue( const string& args, UInterface& ui )
{ {
if( !quiet ) if( !quiet )
cerr << "std::exception: " << ex.what() << endl; cerr << "std::exception: " << ex.what() << endl;
err = 1; err = 1;
} }
} }
...@@ -666,6 +668,7 @@ int getValue( const string& args, UInterface& ui ) ...@@ -666,6 +668,7 @@ int getValue( const string& args, UInterface& ui )
{ {
if( !quiet ) if( !quiet )
cerr << "std::exception: " << ex.what() << endl; cerr << "std::exception: " << ex.what() << endl;
err = 1; err = 1;
} }
} }
...@@ -714,6 +717,7 @@ int getCalibrate( const std::string& args, UInterface& ui ) ...@@ -714,6 +717,7 @@ int getCalibrate( const std::string& args, UInterface& ui )
{ {
if( !quiet ) if( !quiet )
cerr << "std::exception: " << ex.what() << endl; cerr << "std::exception: " << ex.what() << endl;
err = 1; err = 1;
} }
} }
...@@ -758,6 +762,7 @@ int getRawValue( const std::string& args, UInterface& ui ) ...@@ -758,6 +762,7 @@ int getRawValue( const std::string& args, UInterface& ui )
{ {
if( !quiet ) if( !quiet )
cerr << "std::exception: " << ex.what() << endl; cerr << "std::exception: " << ex.what() << endl;
err = 1; err = 1;
} }
} }
...@@ -802,12 +807,14 @@ int getChangedTime( const std::string& args, UInterface& ui ) ...@@ -802,12 +807,14 @@ int getChangedTime( const std::string& args, UInterface& ui )
{ {
if( !quiet ) if( !quiet )
cerr << "CORBA::SystemException: " << ex.NP_minorString() << endl; cerr << "CORBA::SystemException: " << ex.NP_minorString() << endl;
err = 1; err = 1;
} }
catch( const CORBA::Exception& ) catch( const CORBA::Exception& )
{ {
if( !quiet ) if( !quiet )
cerr << "CORBA::Exception." << endl; cerr << "CORBA::Exception." << endl;
err = 1; err = 1;
} }
catch( const omniORB::fatalException& fe ) catch( const omniORB::fatalException& fe )
...@@ -819,20 +826,23 @@ int getChangedTime( const std::string& args, UInterface& ui ) ...@@ -819,20 +826,23 @@ int getChangedTime( const std::string& args, UInterface& ui )
cerr << " line: " << fe.line() << endl; cerr << " line: " << fe.line() << endl;
cerr << " mesg: " << fe.errmsg() << endl; cerr << " mesg: " << fe.errmsg() << endl;
} }
err = 1; err = 1;
} }
catch( const std::exception& ex ) catch( const std::exception& ex )
{ {
if( !quiet ) if( !quiet )
cerr << "std::exception: " << ex.what() << endl; cerr << "std::exception: " << ex.what() << endl;
err = 1; err = 1;
} }
catch(...) catch(...)
{ {
if( !quiet ) if( !quiet )
cerr << "Unknown exception.." << endl; cerr << "Unknown exception.." << endl;
err = 1; err = 1;
} }
} }
return err; return err;
...@@ -971,7 +981,7 @@ int oinfo( const string& args, UInterface& ui ) ...@@ -971,7 +981,7 @@ int oinfo( const string& args, UInterface& ui )
if( !quiet ) if( !quiet )
cerr << "Unknown exception.." << endl; cerr << "Unknown exception.." << endl;
} }
cout << endl << endl; cout << endl << endl;
} }
......
...@@ -25,11 +25,12 @@ print_usage() ...@@ -25,11 +25,12 @@ print_usage()
} }
#parse command line options #parse command line options
TEMP=`getopt -n $PROG -o h,d,c:,s: -l help,dump,confile:,watch_sec: -- "$@"` || exit 1 TEMP=`getopt -n $PROG -o h,d,c:,s: -l help,dump,confile:,watch_sec:,uniset-port: -- "$@"` || exit 1
eval set -- "$TEMP" eval set -- "$TEMP"
dump= dump=
confile= confile=
uport=
while :; do while :; do
case "$1" in case "$1" in
-h|--help) print_usage 0 -h|--help) print_usage 0
...@@ -45,6 +46,10 @@ while :; do ...@@ -45,6 +46,10 @@ while :; do
shift shift
confile="$1" confile="$1"
;; ;;
--uniset-port)
shift
uport="--uniset-port $1"
;;
--) shift; break --) shift; break
;; ;;
*) "unrecognized option: $1" *) "unrecognized option: $1"
...@@ -57,5 +62,5 @@ done ...@@ -57,5 +62,5 @@ done
[ -n "$confile" ] && confile="--confile $confile" [ -n "$confile" ] && confile="--confile $confile"
[ -z "$dump" ] && $WATCH -n $WATCH_SEC uniset2-admin $confile --oinfo $* [ -z "$dump" ] && $WATCH -n $WATCH_SEC uniset2-admin $confile --oinfo $* -- $uport
[ -n "$dump" ] && uniset2-admin $confile --oinfo $* [ -n "$dump" ] && uniset2-admin $confile --oinfo $* -- $uport
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string> #include <string>
#include <getopt.h> #include <getopt.h>
#include "Debug.h" #include "Debug.h"
...@@ -29,6 +28,7 @@ static struct option longopts[] = ...@@ -29,6 +28,7 @@ static struct option longopts[] =
{ "persistent-connection", no_argument, 0, 'o' }, { "persistent-connection", no_argument, 0, 'o' },
{ "num-cycles", required_argument, 0, 'l' }, { "num-cycles", required_argument, 0, 'l' },
{ "sleep-msec", required_argument, 0, 's' }, { "sleep-msec", required_argument, 0, 's' },
{ "check", no_argument, 0, 'n' },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
}; };
...@@ -60,6 +60,7 @@ static void print_help() ...@@ -60,6 +60,7 @@ static void print_help()
printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 - infinitely.\n"); printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 - infinitely.\n");
printf("[-v|--verbose] - Print all messages to stdout\n"); printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-s|--sleep-msec] - send pause. Default: 200 msec\n"); printf("[-s|--sleep-msec] - send pause. Default: 200 msec\n");
printf("[-n|--check] - Check connection for (-i)ip (-p)port\n");
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
enum Command enum Command
...@@ -75,12 +76,11 @@ enum Command ...@@ -75,12 +76,11 @@ enum Command
cmdWrite06, cmdWrite06,
cmdWrite0F, cmdWrite0F,
cmdWrite10, cmdWrite10,
cmdDiag cmdDiag,
cmdCheck
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] ); static char* checkArg( int ind, int argc, char* argv[] );
// --------------------------------------------------------------------------
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
// std::ios::sync_with_stdio(false); // std::ios::sync_with_stdio(false);
...@@ -121,7 +121,7 @@ int main( int argc, char** argv ) ...@@ -121,7 +121,7 @@ int main( int argc, char** argv )
try try
{ {
while( (opt = getopt_long(argc, argv, "hva:w:z:r:x:c:b:d:s:t:p:i:ol:d:e:u:", longopts, &optindex)) != -1 ) while( (opt = getopt_long(argc, argv, "hvna:w:z:r:x:c:b:d:s:t:p:i:ol:d:e:u:", longopts, &optindex)) != -1 )
{ {
switch (opt) switch (opt)
{ {
...@@ -137,6 +137,7 @@ int main( int argc, char** argv ) ...@@ -137,6 +137,7 @@ int main( int argc, char** argv )
if( cmd == cmdNOP ) if( cmd == cmdNOP )
cmd = cmdRead02; cmd = cmdRead02;
case 'r': case 'r':
if( cmd == cmdNOP ) if( cmd == cmdNOP )
cmd = cmdRead03; cmd = cmdRead03;
...@@ -162,6 +163,10 @@ int main( int argc, char** argv ) ...@@ -162,6 +163,10 @@ int main( int argc, char** argv )
} }
break; break;
case 'n':
cmd = cmdCheck;
break;
case 'e': case 'e':
{ {
if( cmd == cmdNOP ) if( cmd == cmdNOP )
...@@ -602,6 +607,13 @@ int main( int argc, char** argv ) ...@@ -602,6 +607,13 @@ int main( int argc, char** argv )
} }
break; break;
case cmdCheck:
{
bool res = ModbusTCPMaster::checkConnection(iaddr, port, tout);
cout << iaddr << ":" << port << " connection " << (res ? "OK" : "FAIL") << endl;
}
break;
case cmdNOP: case cmdNOP:
default: default:
cerr << "No command. Use -h for help." << endl; cerr << "No command. Use -h for help." << endl;
...@@ -662,3 +674,8 @@ char* checkArg( int i, int argc, char* argv[] ) ...@@ -662,3 +674,8 @@ char* checkArg( int i, int argc, char* argv[] )
return 0; return 0;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void ping( const std::string& iaddr, int port )
{
cerr << "ping2: check connection " << ModbusTCPMaster::checkConnection(iaddr, port, 1000) << endl;
}
// --------------------------------------------------------------------------
...@@ -76,7 +76,6 @@ int main( int argc, char** argv ) ...@@ -76,7 +76,6 @@ int main( int argc, char** argv )
int cmdonly = 0; int cmdonly = 0;
timeout_t tout = 0; timeout_t tout = 0;
timeout_t rdelay = 5000; timeout_t rdelay = 5000;
bool cmdlist = false;
try try
{ {
...@@ -140,7 +139,6 @@ int main( int argc, char** argv ) ...@@ -140,7 +139,6 @@ int main( int argc, char** argv )
filter = string(arg2); filter = string(arg2);
vcmd.push_back( LogReader::Command(LogServerTypes::cmdList, 0, filter) ); vcmd.push_back( LogReader::Command(LogServerTypes::cmdList, 0, filter) );
cmdlist = true;
} }
break; break;
...@@ -239,15 +237,6 @@ int main( int argc, char** argv ) ...@@ -239,15 +237,6 @@ int main( int argc, char** argv )
lr.setinTimeout(tout); lr.setinTimeout(tout);
lr.setReconnectDelay(rdelay); lr.setReconnectDelay(rdelay);
/*
if( cmdlist && vcmd.size() == 1 )
{
cmdonly = 1;
lr.setReadCount(1);
lr.sendCommand(addr, port, vcmd, cmdonly, verb);
return 0;
}
*/
if( !vcmd.empty() ) if( !vcmd.empty() )
lr.sendCommand(addr, port, vcmd, cmdonly, verb); lr.sendCommand(addr, port, vcmd, cmdonly, verb);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
Name: libuniset2 Name: libuniset2
Version: 2.1 Version: 2.1
Release: alt15.1 Release: alt25
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
...@@ -456,6 +456,50 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -456,6 +456,50 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# .. # ..
%changelog %changelog
* Mon Sep 14 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt25
- (PassiveTimer): fixed bug in default init
- (Pulse): refactoring
* Thu Sep 10 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt24
- (LogServer): refactoring (more use shared_ptr)
* Mon Sep 07 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt23
- (ModbusPersistentSlave): fixed bug in end connection processing
- (uniset-log): fixed bug in end connection processing
* Sun Sep 06 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt22
- refactoring (use shared_ptr), change pollfactor realisation..
* Sat Sep 05 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt21
- (modbus slave): add more logs..
* Sat Aug 29 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt20
- (ModbusSession): add setKeepAliveParams()
* Sat Aug 29 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt19
- (ModbusSlave): rename ModbusMultiSlave --> ModbusPersistentSlave, minor fixes
* Thu Aug 27 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt18
- (ModbusExchange): add reinit_timeout timer..
* Fri Aug 21 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt17
- up build
* Fri Aug 21 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt16.2
- (ModbusTCP): fixed bug in update respond sensor in SharedMemory
* Thu Aug 20 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt16.1
- (ModbusTCP): add more vmonit parameters
* Thu Aug 20 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt16
- (modbustcptest): add 'check' for connection
* Tue Aug 18 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt15.3
- minor build
* Fri Aug 14 2015 Pavel Vainerman <pv@etersoft.ru> 2.1-alt15.2
- up build
* Thu Aug 13 2015 Pavel Vainerman <pv@etersoft.ru> 2.1-alt15.1 * Thu Aug 13 2015 Pavel Vainerman <pv@etersoft.ru> 2.1-alt15.1
- test build for new UNetUDP - test build for new UNetUDP
......
...@@ -78,9 +78,9 @@ ...@@ -78,9 +78,9 @@
<item addr="0x01" invert="0" respondSensor="RespondRTU_S" timeout="5000" modeSensor="MB1_Mode_AS"/> <item addr="0x01" invert="0" respondSensor="RespondRTU_S" timeout="5000" modeSensor="MB1_Mode_AS"/>
</DeviceList> </DeviceList>
</MBMaster1> </MBMaster1>
<MBMultiMaster1 levels="info,warn,crit" name="MBMaster1" poll_time="200" reply_timeout="60"> <MBMultiMaster1 levels="info,warn,crit" name="MBMaster1" polltime="200">
<DeviceList> <DeviceList>
<item addr="0x01" invert="0" respondSensor="RespondRTU_S" timeout="5000" modeSensor="MB1_Mode_AS"/> <item addr="0x01" invert="1" force="0" respondSensor="RespondRTU_S" timeout="1000" modeSensor="MB1_Mode_AS"/>
</DeviceList> </DeviceList>
<GateList> <GateList>
<item ip="localhost" port="2048" recv_timeout="800" invert="1" respondSensor="MM1_Not_Respond_S"/> <item ip="localhost" port="2048" recv_timeout="800" invert="1" respondSensor="MM1_Not_Respond_S"/>
......
...@@ -96,6 +96,9 @@ MBExchange::MBExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId ...@@ -96,6 +96,9 @@ MBExchange::MBExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId
ptReopen.setTiming(tout); ptReopen.setTiming(tout);
vmonit(recv_timeout); vmonit(recv_timeout);
int reinit_tout = conf->getArgPInt("--" + prefix + "-reinit-timeout", it.getProp("reinit_timeout"), default_timeout);
ptInitChannel.setTiming(reinit_tout);
aftersend_pause = conf->getArgPInt("--" + prefix + "-aftersend-pause", it.getProp("aftersend_pause"), 0); aftersend_pause = conf->getArgPInt("--" + prefix + "-aftersend-pause", it.getProp("aftersend_pause"), 0);
vmonit(aftersend_pause); vmonit(aftersend_pause);
...@@ -260,33 +263,6 @@ void MBExchange::help_print( int argc, const char* const* argv ) ...@@ -260,33 +263,6 @@ void MBExchange::help_print( int argc, const char* const* argv )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBExchange::~MBExchange() MBExchange::~MBExchange()
{ {
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 )
{
if( it1->second->rtu )
{
try
{
delete it1->second->rtu;
it1->second->rtu = 0;
}
catch(...) {}
}
RTUDevice* d(it1->second);
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it )
{
try
{
delete it->second;
}
catch(...) {}
}
delete it1->second;
}
mb.reset();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::waitSMReady() void MBExchange::waitSMReady()
...@@ -316,7 +292,8 @@ void MBExchange::step() ...@@ -316,7 +292,8 @@ void MBExchange::step()
if( !checkProcActive() ) if( !checkProcActive() )
return; return;
updateRespondSensors(); if( ptInitChannel.checkTime() )
updateRespondSensors();
if( sidHeartBeat != DefaultObjectId && ptHeartBeat.checkTime() ) if( sidHeartBeat != DefaultObjectId && ptHeartBeat.checkTime() )
{ {
...@@ -419,18 +396,22 @@ void MBExchange::initIterators() ...@@ -419,18 +396,22 @@ void MBExchange::initIterators()
shm->initIterator(itHeartBeat); shm->initIterator(itHeartBeat);
shm->initIterator(itExchangeMode); shm->initIterator(itExchangeMode);
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
RTUDevice* d(it1->second); auto d = it1->second;
shm->initIterator(d->resp_it); shm->initIterator(d->resp_it);
shm->initIterator(d->mode_it); shm->initIterator(d->mode_it);
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it ) for( auto&& m: d->pollmap )
{ {
for( auto it2 = it->second->slst.begin(); it2 != it->second->slst.end(); ++it2 ) auto& regmap = m.second;
for( auto it = regmap->begin(); it != regmap->end(); ++it )
{ {
shm->initIterator(it2->ioit); for( auto it2 = it->second->slst.begin(); it2 != it->second->slst.end(); ++it2 )
shm->initIterator(it2->t_ait); {
shm->initIterator(it2->ioit);
shm->initIterator(it2->t_ait);
}
} }
} }
} }
...@@ -444,18 +425,22 @@ void MBExchange::initIterators() ...@@ -444,18 +425,22 @@ void MBExchange::initIterators()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::initValues() void MBExchange::initValues()
{ {
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
RTUDevice* d(it1->second); auto d = it1->second;
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it ) for( auto&& m: d->pollmap )
{ {
for( auto it2 = it->second->slst.begin(); it2 != it->second->slst.end(); ++it2 ) auto regmap = m.second;
for( auto it = regmap->begin(); it != regmap->end(); ++it )
{ {
it2->value = shm->localGetValue(it2->ioit, it2->si.id); for( auto it2 = it->second->slst.begin(); it2 != it->second->slst.end(); ++it2 )
} {
it2->value = shm->localGetValue(it2->ioit, it2->si.id);
}
it->second->sm_initOK = true; it->second->sm_initOK = true;
}
} }
} }
...@@ -555,8 +540,11 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RTUDevice& d ) ...@@ -555,8 +540,11 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RTUDevice& d )
os << " regs: " << endl; os << " regs: " << endl;
for( auto it = d.regmap.begin(); it != d.regmap.end(); ++it ) for( const auto& m: d.pollmap )
os << " " << *(it->second) << endl; {
for( const auto& it: *(m.second) )
os << " " << it.second << endl;
}
return os; return os;
} }
...@@ -583,70 +571,75 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RegInfo& r ) ...@@ -583,70 +571,75 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RegInfo& r )
return os; return os;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::rtuQueryOptimization( RTUDeviceMap& m ) void MBExchange::rtuQueryOptimization( RTUDeviceMap& dm )
{ {
if( noQueryOptimization ) if( noQueryOptimization )
return; return;
mbinfo << myname << "(rtuQueryOptimization): optimization..." << endl; mbinfo << myname << "(rtuQueryOptimization): optimization..." << endl;
for( auto it1 = m.begin(); it1 != m.end(); ++it1 ) for( auto&& it1: dm )
{ {
RTUDevice* d(it1->second); auto d = it1.second;
// Вообще в map они уже лежат в нужном порядке, т.е. функция genRegID() гарантирует for( auto&& m: d->pollmap )
// что регистры идущие подряд с одниковой функцией чтения/записи получат подряд идущие ID.
// так что оптимтизация это просто нахождение мест где id идут не подряд...
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it )
{ {
auto beg = it; auto& regmap = m.second;
ModbusRTU::RegID id = it->second->id; // или собственно it->first
beg->second->q_num = 1;
beg->second->q_count = 1;
++it;
for( ; it != d->regmap.end(); ++it ) // Вообще в map они уже лежат в нужном порядке, т.е. функция genRegID() гарантирует
// что регистры идущие подряд с одниковой функцией чтения/записи получат подряд идущие ID.
// так что оптимтизация это просто нахождение мест где id идут не подряд...
for( auto it = regmap->begin(); it != regmap->end(); ++it )
{ {
if( (it->second->id - id) > 1 ) auto beg = it;
ModbusRTU::RegID id = it->second->id; // или собственно it->first
beg->second->q_num = 1;
beg->second->q_count = 1;
++it;
for( ; it != regmap->end(); ++it )
{ {
--it; // раз это регистр уже следующий, то надо вернуть на шаг обратно.. if( (it->second->id - id) > 1 )
break; {
} --it; // раз это регистр уже следующий, то надо вернуть на шаг обратно..
break;
}
beg->second->q_count++; beg->second->q_count++;
if( beg->second->q_count >= maxQueryCount ) if( beg->second->q_count >= maxQueryCount )
break; break;
id = it->second->id; id = it->second->id;
it->second->q_num = beg->second->q_count; it->second->q_num = beg->second->q_count;
it->second->q_count = 0; it->second->q_count = 0;
} }
// check correct function... // check correct function...
if( beg->second->q_count > 1 && beg->second->mbfunc == ModbusRTU::fnWriteOutputSingleRegister ) if( beg->second->q_count > 1 && beg->second->mbfunc == ModbusRTU::fnWriteOutputSingleRegister )
{ {
mbwarn << myname << "(rtuQueryOptimization): " mbwarn << myname << "(rtuQueryOptimization): "
<< " optimization change func=" << ModbusRTU::fnWriteOutputSingleRegister << " optimization change func=" << ModbusRTU::fnWriteOutputSingleRegister
<< " <--> func=" << ModbusRTU::fnWriteOutputRegisters << " <--> func=" << ModbusRTU::fnWriteOutputRegisters
<< " for mbaddr=" << ModbusRTU::addr2str(d->mbaddr) << " for mbaddr=" << ModbusRTU::addr2str(d->mbaddr)
<< " mbreg=" << ModbusRTU::dat2str(beg->second->mbreg); << " mbreg=" << ModbusRTU::dat2str(beg->second->mbreg);
beg->second->mbfunc = ModbusRTU::fnWriteOutputRegisters; beg->second->mbfunc = ModbusRTU::fnWriteOutputRegisters;
} }
else if( beg->second->q_count > 1 && beg->second->mbfunc == ModbusRTU::fnForceSingleCoil ) else if( beg->second->q_count > 1 && beg->second->mbfunc == ModbusRTU::fnForceSingleCoil )
{ {
mbwarn << myname << "(rtuQueryOptimization): " mbwarn << myname << "(rtuQueryOptimization): "
<< " optimization change func=" << ModbusRTU::fnForceSingleCoil << " optimization change func=" << ModbusRTU::fnForceSingleCoil
<< " <--> func=" << ModbusRTU::fnForceMultipleCoils << " <--> func=" << ModbusRTU::fnForceMultipleCoils
<< " for mbaddr=" << ModbusRTU::addr2str(d->mbaddr) << " for mbaddr=" << ModbusRTU::addr2str(d->mbaddr)
<< " mbreg=" << ModbusRTU::dat2str(beg->second->mbreg); << " mbreg=" << ModbusRTU::dat2str(beg->second->mbreg);
beg->second->mbfunc = ModbusRTU::fnForceMultipleCoils; beg->second->mbfunc = ModbusRTU::fnForceMultipleCoils;
} }
if( it == d->regmap.end() ) if( it == regmap->end() )
break; break;
}
} }
} }
} }
...@@ -696,7 +689,7 @@ bool MBExchange::preInitRead( InitList::iterator& p ) ...@@ -696,7 +689,7 @@ bool MBExchange::preInitRead( InitList::iterator& p )
if( p->initOK ) if( p->initOK )
return true; return true;
RTUDevice* dev = p->dev; auto dev = p->dev;
int q_count = p->p.rnum; int q_count = p->p.rnum;
if( mblog->is_level3() ) if( mblog->is_level3() )
...@@ -929,9 +922,9 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty ...@@ -929,9 +922,9 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
return false; return false;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) bool MBExchange::pollRTU( std::shared_ptr<RTUDevice>& dev, RegMap::iterator& it )
{ {
RegInfo* p(it->second); auto p = it->second;
if( dev->mode == emSkipExchange ) if( dev->mode == emSkipExchange )
{ {
...@@ -941,9 +934,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -941,9 +934,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
return false; return false;
} }
if( p->pollfactor>1 && ncycle%p->pollfactor!=0 )
return false;
if( mblog->is_level3() ) if( mblog->is_level3() )
{ {
mblog3 << myname << "(pollRTU): poll " mblog3 << myname << "(pollRTU): poll "
...@@ -954,7 +944,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -954,7 +944,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
<< " mb_initOK=" << p->mb_initOK << " mb_initOK=" << p->mb_initOK
<< " sm_initOK=" << p->sm_initOK << " sm_initOK=" << p->sm_initOK
<< " mbval=" << p->mbval << " mbval=" << p->mbval
<< " pollfactor=" << p->pollfactor
<< endl; << endl;
if( p->q_count > maxQueryCount /* ModbusRTU::MAXDATALEN */ ) if( p->q_count > maxQueryCount /* ModbusRTU::MAXDATALEN */ )
...@@ -1149,9 +1138,9 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -1149,9 +1138,9 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::updateSM() void MBExchange::updateSM()
{ {
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
RTUDevice* d(it1->second); auto d = it1->second;
if( d->mode_id != DefaultObjectId ) if( d->mode_id != DefaultObjectId )
{ {
...@@ -1187,50 +1176,56 @@ void MBExchange::updateSM() ...@@ -1187,50 +1176,56 @@ void MBExchange::updateSM()
} }
} }
// обновление датчиков связи происходит в другом потоке
// чтобы не зависеть от TCP таймаутов
// см. updateRespondSensors()
// update values... for( auto&& m: d->pollmap )
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it )
{ {
try auto& regmap = m.second;
{
if( d->dtype == dtRTU ) // обновление датчиков связи происходит в другом потоке
updateRTU(it); // чтобы не зависеть от TCP таймаутов
else if( d->dtype == dtMTR ) // см. updateRespondSensors()
updateMTR(it);
else if( d->dtype == dtRTU188 ) // update values...
updateRTU188(it); for( auto it = regmap->begin(); it != regmap->end(); ++it )
}
catch(IOController_i::NameNotFound& ex)
{
mblog3 << myname << "(updateSM):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
mblog3 << myname << "(updateSM):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
mblog3 << myname << "(updateSM): (BadRange)..." << endl;
}
catch( const Exception& ex )
{
mblog3 << myname << "(updateSM): " << ex << endl;
}
catch( const CORBA::SystemException& ex )
{
mblog3 << myname << "(updateSM): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch( const std::exception& ex )
{ {
mblog3 << myname << "(updateSM): catch ..." << endl; try
} {
if( d->dtype == dtRTU )
updateRTU(it);
else if( d->dtype == dtMTR )
updateMTR(it);
else if( d->dtype == dtRTU188 )
updateRTU188(it);
}
catch(IOController_i::NameNotFound& ex)
{
mblog3 << myname << "(updateSM):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
mblog3 << myname << "(updateSM):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
mblog3 << myname << "(updateSM): (BadRange)..." << endl;
}
catch( const Exception& ex )
{
mblog3 << myname << "(updateSM): " << ex << endl;
}
catch( const CORBA::SystemException& ex )
{
mblog3 << myname << "(updateSM): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch( const std::exception& ex )
{
mblog3 << myname << "(updateSM): catch ..." << endl;
}
if( it == d->regmap.end() ) if( it == regmap->end() )
break; break;
}
} }
} }
} }
...@@ -1238,17 +1233,17 @@ void MBExchange::updateSM() ...@@ -1238,17 +1233,17 @@ void MBExchange::updateSM()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::updateRTU( RegMap::iterator& rit ) void MBExchange::updateRTU( RegMap::iterator& rit )
{ {
RegInfo* r(rit->second); auto& r = rit->second;
for( auto it = r->slst.begin(); it != r->slst.end(); ++it ) for( auto&& it: r->slst )
updateRSProperty( &(*it), false ); updateRSProperty( &it, false );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::updateRSProperty( RSProperty* p, bool write_only ) void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
{ {
using namespace ModbusRTU; using namespace ModbusRTU;
RegInfo* r(p->reg->rit->second); auto& r = p->reg->rit->second;
bool save = isWriteFunction( r->mbfunc ); bool save = isWriteFunction( r->mbfunc );
...@@ -1650,7 +1645,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only ) ...@@ -1650,7 +1645,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::updateMTR( RegMap::iterator& rit ) void MBExchange::updateMTR( RegMap::iterator& rit )
{ {
RegInfo* r(rit->second); auto& r = rit->second;
if( !r || !r->dev ) if( !r || !r->dev )
return; return;
...@@ -1908,9 +1903,9 @@ void MBExchange::updateMTR( RegMap::iterator& rit ) ...@@ -1908,9 +1903,9 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::updateRTU188( RegMap::iterator& rit ) void MBExchange::updateRTU188( RegMap::iterator& rit )
{ {
RegInfo* r(rit->second); auto& r = rit->second;
if( !r || !r->dev || !r->dev->rtu ) if( !r || !r->dev || !r->dev->rtu188 )
return; return;
using namespace ModbusRTU; using namespace ModbusRTU;
...@@ -1959,12 +1954,12 @@ void MBExchange::updateRTU188( RegMap::iterator& rit ) ...@@ -1959,12 +1954,12 @@ void MBExchange::updateRTU188( RegMap::iterator& rit )
{ {
if( it->stype == UniversalIO::DI ) if( it->stype == UniversalIO::DI )
{ {
bool set = r->dev->rtu->getState(r->rtuJack, r->rtuChan, it->stype); bool set = r->dev->rtu188->getState(r->rtuJack, r->rtuChan, it->stype);
IOBase::processingAsDI( &(*it), set, shm, force ); IOBase::processingAsDI( &(*it), set, shm, force );
} }
else if( it->stype == UniversalIO::AI ) else if( it->stype == UniversalIO::AI )
{ {
long val = r->dev->rtu->getInt(r->rtuJack, r->rtuChan, it->stype); long val = r->dev->rtu188->getInt(r->rtuJack, r->rtuChan, it->stype);
IOBase::processingAsAI( &(*it), val, shm, force ); IOBase::processingAsAI( &(*it), val, shm, force );
} }
} }
...@@ -1997,7 +1992,7 @@ void MBExchange::updateRTU188( RegMap::iterator& rit ) ...@@ -1997,7 +1992,7 @@ void MBExchange::updateRTU188( RegMap::iterator& rit )
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAddr a, UniXML::iterator& xmlit ) std::shared_ptr<MBExchange::RTUDevice> MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAddr a, UniXML::iterator& xmlit )
{ {
auto it = mp.find(a); auto it = mp.find(a);
...@@ -2024,12 +2019,12 @@ MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAd ...@@ -2024,12 +2019,12 @@ MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAd
return it->second; return it->second;
} }
MBExchange::RTUDevice* d = new MBExchange::RTUDevice(); auto d = make_shared<MBExchange::RTUDevice>();
d->mbaddr = a; d->mbaddr = a;
if( !initRTUDevice(d, xmlit) ) if( !initRTUDevice(d, xmlit) )
{ {
delete d; d.reset();
return 0; return 0;
} }
...@@ -2037,12 +2032,12 @@ MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAd ...@@ -2037,12 +2032,12 @@ MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAd
return d; return d;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
MBExchange::RegInfo* MBExchange::addReg( RegMap& mp, ModbusRTU::RegID id, ModbusRTU::ModbusData r, std::shared_ptr<MBExchange::RegInfo> MBExchange::addReg( std::shared_ptr<RegMap>& mp, ModbusRTU::RegID id, ModbusRTU::ModbusData r,
UniXML::iterator& xmlit, MBExchange::RTUDevice* dev ) UniXML::iterator& xmlit, std::shared_ptr<MBExchange::RTUDevice> dev )
{ {
auto it = mp.find(id); auto it = mp->find(id);
if( it != mp.end() ) if( it != mp->end() )
{ {
if( !it->second->dev ) if( !it->second->dev )
{ {
...@@ -2067,26 +2062,25 @@ MBExchange::RegInfo* MBExchange::addReg( RegMap& mp, ModbusRTU::RegID id, Modbus ...@@ -2067,26 +2062,25 @@ MBExchange::RegInfo* MBExchange::addReg( RegMap& mp, ModbusRTU::RegID id, Modbus
return it->second; return it->second;
} }
MBExchange::RegInfo* ri = new MBExchange::RegInfo(); auto ri = make_shared<MBExchange::RegInfo>();
if( !initRegInfo(ri, xmlit, dev) ) if( !initRegInfo(ri, xmlit, dev) )
{
delete ri;
return 0; return 0;
}
ri->mbreg = r; ri->mbreg = r;
ri->id = id; ri->id = id;
mp.insert(std::make_pair(id, ri)); mp->insert( std::make_pair(id, ri) );
ri->rit = mp.find(id); ri->rit = mp->find(id);
mbinfo << myname << "(addReg): reg=" << ModbusRTU::dat2str(r) << "(id=" << id << ")" << endl;
return ri; return ri;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
MBExchange::RSProperty* MBExchange::addProp( PList& plist, RSProperty&& p ) MBExchange::RSProperty* MBExchange::addProp( PList& plist, RSProperty&& p )
{ {
for( auto& it : plist ) for( auto && it : plist )
{ {
if( it.si.id == p.si.id && it.si.node == p.si.node ) if( it.si.id == p.si.id && it.si.node == p.si.node )
return &it; return &it;
...@@ -2176,12 +2170,10 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML::iterator& it ) ...@@ -2176,12 +2170,10 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML::iterator& it )
return true; return true;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool MBExchange::initRegInfo( RegInfo* r, UniXML::iterator& it, MBExchange::RTUDevice* dev ) bool MBExchange::initRegInfo( std::shared_ptr<RegInfo>& r, UniXML::iterator& it, std::shared_ptr<MBExchange::RTUDevice>& dev )
{ {
r->dev = dev; r->dev = dev;
r->mbval = IOBase::initIntProp(it, "default", prop_prefix, false); r->mbval = IOBase::initIntProp(it, "default", prop_prefix, false);
r->pollfactor = IOBase::initIntProp(it, "pollfactor", prop_prefix, false,0);
if( dev->dtype == MBExchange::dtRTU ) if( dev->dtype == MBExchange::dtRTU )
{ {
...@@ -2253,7 +2245,7 @@ bool MBExchange::initRegInfo( RegInfo* r, UniXML::iterator& it, MBExchange::RTU ...@@ -2253,7 +2245,7 @@ bool MBExchange::initRegInfo( RegInfo* r, UniXML::iterator& it, MBExchange::RTU
return true; return true;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool MBExchange::initRTUDevice( RTUDevice* d, UniXML::iterator& it ) bool MBExchange::initRTUDevice( std::shared_ptr<RTUDevice>& d, UniXML::iterator& it )
{ {
string mbtype(IOBase::initProp(it, "mbtype", prop_prefix, false)); string mbtype(IOBase::initProp(it, "mbtype", prop_prefix, false));
...@@ -2285,8 +2277,8 @@ bool MBExchange::initRTUDevice( RTUDevice* d, UniXML::iterator& it ) ...@@ -2285,8 +2277,8 @@ bool MBExchange::initRTUDevice( RTUDevice* d, UniXML::iterator& it )
if( d->dtype == MBExchange::dtRTU188 ) if( d->dtype == MBExchange::dtRTU188 )
{ {
if( !d->rtu ) if( !d->rtu188 )
d->rtu = new RTUStorage(d->mbaddr); d->rtu188 = make_shared<RTUStorage>(d->mbaddr);
} }
return true; return true;
...@@ -2315,7 +2307,7 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2315,7 +2307,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
ModbusRTU::ModbusAddr mbaddr = ModbusRTU::str2mbAddr(addr); ModbusRTU::ModbusAddr mbaddr = ModbusRTU::str2mbAddr(addr);
RTUDevice* dev = addDev(rmap, mbaddr, it); auto dev = addDev(devices, mbaddr, it);
if( !dev ) if( !dev )
{ {
...@@ -2328,16 +2320,17 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2328,16 +2320,17 @@ bool MBExchange::initItem( UniXML::iterator& it )
if( dev->dtype == dtRTU188 ) if( dev->dtype == dtRTU188 )
{ {
RegInfo r_tmp; auto r_tmp = make_shared<RegInfo>();
if( !initRTU188item(it, &r_tmp) ) if( !initRTU188item(it, r_tmp) )
{ {
mbcrit << myname << "(initItem): init RTU188 failed for " << it.getProp("name") << endl; mbcrit << myname << "(initItem): init RTU188 failed for " << it.getProp("name") << endl;
r_tmp.reset();
return false; return false;
} }
mbreg = RTUStorage::getRegister(r_tmp.rtuJack, r_tmp.rtuChan, p.stype); mbreg = RTUStorage::getRegister(r_tmp->rtuJack, r_tmp->rtuChan, p.stype);
fn = RTUStorage::getFunction(r_tmp.rtuJack, r_tmp.rtuChan, p.stype); fn = RTUStorage::getFunction(r_tmp->rtuJack, r_tmp->rtuChan, p.stype);
} }
else else
{ {
...@@ -2367,13 +2360,29 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2367,13 +2360,29 @@ bool MBExchange::initItem( UniXML::iterator& it )
} }
} }
/*! приоритет опроса:
* 1...n - задаёт "часоту" опроса. Т.е. каждые 1...n циклов
*/
unsigned int pollfactor = IOBase::initIntProp(it, "pollfactor", prop_prefix, false, 0);
std::shared_ptr<RegMap> rmap;
auto rit = dev->pollmap.find(pollfactor);
if( rit == dev->pollmap.end() )
{
rmap = make_shared<RegMap>();
dev->pollmap.emplace(pollfactor,rmap);
}
else
rmap = rit->second;
// формула для вычисления ID // формула для вычисления ID
// требования: // требования:
// - ID > диапазона возможных регитров // - ID > диапазона возможных регитров
// - разные функции должны давать разный ID // - разные функции должны давать разный ID
ModbusRTU::RegID rID = ModbusRTU::genRegID(mbreg, fn); ModbusRTU::RegID rID = ModbusRTU::genRegID(mbreg, fn);
RegInfo* ri = addReg(dev->regmap, rID, mbreg, it, dev); auto ri = addReg(rmap, rID, mbreg, it, dev);
if( dev->dtype == dtMTR ) if( dev->dtype == dtMTR )
{ {
...@@ -2409,7 +2418,7 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2409,7 +2418,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
ostringstream sl; ostringstream sl;
sl << "[ "; sl << "[ ";
for( auto& i : ri->slst ) for( const auto& i : ri->slst )
sl << ORepHelpers::getShortName(conf->oind->getMapName(i.si.id)) << ","; sl << ORepHelpers::getShortName(conf->oind->getMapName(i.si.id)) << ",";
sl << "]"; sl << "]";
...@@ -2464,7 +2473,7 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2464,7 +2473,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
for( auto i = 1; i < p1->rnum; i++ ) for( auto i = 1; i < p1->rnum; i++ )
{ {
ModbusRTU::RegID id1 = ModbusRTU::genRegID(mbreg + i, ri->mbfunc); ModbusRTU::RegID id1 = ModbusRTU::genRegID(mbreg + i, ri->mbfunc);
RegInfo* r = addReg(dev->regmap, id1, mbreg + i, it, dev); auto r = addReg(rmap, id1, mbreg + i, it, dev);
r->q_num = i + 1; r->q_num = i + 1;
r->q_count = 1; r->q_count = 1;
r->mbfunc = ri->mbfunc; r->mbfunc = ri->mbfunc;
...@@ -2554,7 +2563,7 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2554,7 +2563,7 @@ bool MBExchange::initItem( UniXML::iterator& it )
return true; return true;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool MBExchange::initMTRitem( UniXML::iterator& it, RegInfo* p ) bool MBExchange::initMTRitem( UniXML::iterator& it, std::shared_ptr<RegInfo>& p )
{ {
p->mtrType = MTR::str2type(it.getProp(prop_prefix + "mtrtype")); p->mtrType = MTR::str2type(it.getProp(prop_prefix + "mtrtype"));
...@@ -2570,7 +2579,7 @@ bool MBExchange::initMTRitem( UniXML::iterator& it, RegInfo* p ) ...@@ -2570,7 +2579,7 @@ bool MBExchange::initMTRitem( UniXML::iterator& it, RegInfo* p )
return true; return true;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool MBExchange::initRTU188item( UniXML::iterator& it, RegInfo* p ) bool MBExchange::initRTU188item( UniXML::iterator& it, std::shared_ptr<RegInfo>& p )
{ {
string jack(IOBase::initProp(it, "jakc", prop_prefix, false)); string jack(IOBase::initProp(it, "jakc", prop_prefix, false));
string chan(IOBase::initProp(it, "channel", prop_prefix, false)); string chan(IOBase::initProp(it, "channel", prop_prefix, false));
...@@ -2668,7 +2677,7 @@ void MBExchange::initDeviceList() ...@@ -2668,7 +2677,7 @@ void MBExchange::initDeviceList()
for(; it1.getCurrent(); it1.goNext() ) for(; it1.getCurrent(); it1.goNext() )
{ {
ModbusRTU::ModbusAddr a = ModbusRTU::str2mbAddr(it1.getProp("addr")); ModbusRTU::ModbusAddr a = ModbusRTU::str2mbAddr(it1.getProp("addr"));
initDeviceInfo(rmap, a, it1); initDeviceInfo(devices, a, it1);
} }
} }
else else
...@@ -2753,7 +2762,7 @@ bool MBExchange::activateObject() ...@@ -2753,7 +2762,7 @@ bool MBExchange::activateObject()
UniSetObject_LT::activateObject(); UniSetObject_LT::activateObject();
if( !shm->isLocalwork() ) if( !shm->isLocalwork() )
rtuQueryOptimization(rmap); rtuQueryOptimization(devices);
initIterators(); initIterators();
setProcActive(true); setProcActive(true);
...@@ -2774,14 +2783,14 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage* sm ) ...@@ -2774,14 +2783,14 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage* sm )
logserv->run(logserv_host, logserv_port, true); logserv->run(logserv_host, logserv_port, true);
} }
if( rmap.empty() ) if( devices.empty() )
{ {
mbcrit << myname << "(sysCommand): ************* ITEM MAP EMPTY! terminated... *************" << endl; mbcrit << myname << "(sysCommand): ************* ITEM MAP EMPTY! terminated... *************" << endl;
raise(SIGTERM); raise(SIGTERM);
return; return;
} }
mbinfo << myname << "(sysCommand): device map size= " << rmap.size() << endl; mbinfo << myname << "(sysCommand): device map size= " << devices.size() << endl;
if( !shm->isLocalwork() ) if( !shm->isLocalwork() )
initDeviceList(); initDeviceList();
...@@ -2896,9 +2905,9 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd ) ...@@ -2896,9 +2905,9 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
mbwarn << myname << "(askSensors): 'sidExchangeMode' catch..." << std::endl; mbwarn << myname << "(askSensors): 'sidExchangeMode' catch..." << std::endl;
} }
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
RTUDevice* d(it1->second); auto d = it1->second;
try try
{ {
...@@ -2917,24 +2926,28 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd ) ...@@ -2917,24 +2926,28 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
if( force_out ) if( force_out )
return; return;
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it ) for( auto&& m: d->pollmap )
{ {
if( !isWriteFunction(it->second->mbfunc) ) auto& regmap = m.second;
continue; for( auto it = regmap->begin(); it != regmap->end(); ++it )
for( auto i = it->second->slst.begin(); i != it->second->slst.end(); ++i )
{ {
try if( !isWriteFunction(it->second->mbfunc) )
{ continue;
shm->askSensor(i->si.id, cmd);
} for( auto i = it->second->slst.begin(); i != it->second->slst.end(); ++i )
catch( UniSetTypes::Exception& ex )
{
mbwarn << myname << "(askSensors): " << ex << std::endl;
}
catch(...)
{ {
mbwarn << myname << "(askSensors): id=" << i->si.id << " catch..." << std::endl; try
{
shm->askSensor(i->si.id, cmd);
}
catch( UniSetTypes::Exception& ex )
{
mbwarn << myname << "(askSensors): " << ex << std::endl;
}
catch(...)
{
mbwarn << myname << "(askSensors): id=" << i->si.id << " catch..." << std::endl;
}
} }
} }
} }
...@@ -2950,9 +2963,9 @@ void MBExchange::sensorInfo( const UniSetTypes::SensorMessage* sm ) ...@@ -2950,9 +2963,9 @@ void MBExchange::sensorInfo( const UniSetTypes::SensorMessage* sm )
//return; // этот датчик может встречаться и в списке обмена.. поэтому делать return нельзя. //return; // этот датчик может встречаться и в списке обмена.. поэтому делать return нельзя.
} }
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
RTUDevice* d(it1->second); auto d(it1->second);
if( sm->id == d->mode_id ) if( sm->id == d->mode_id )
d->mode = sm->value; d->mode = sm->value;
...@@ -2960,26 +2973,31 @@ void MBExchange::sensorInfo( const UniSetTypes::SensorMessage* sm ) ...@@ -2960,26 +2973,31 @@ void MBExchange::sensorInfo( const UniSetTypes::SensorMessage* sm )
if( force_out ) if( force_out )
continue; continue;
for( auto& it : d->regmap ) for( const auto& m : d->pollmap )
{ {
if( !isWriteFunction(it.second->mbfunc) ) auto&& regmap = m.second;
continue;
for( auto& i : it.second->slst ) for( const auto& it: (*regmap) )
{ {
if( sm->id == i.si.id && sm->node == i.si.node ) if( !isWriteFunction(it.second->mbfunc) )
continue;
for( auto && i : it.second->slst )
{ {
mbinfo << myname << "(sensorInfo): si.id=" << sm->id if( sm->id == i.si.id && sm->node == i.si.node )
<< " reg=" << ModbusRTU::dat2str(i.reg->mbreg) {
<< " val=" << sm->value mbinfo << myname << "(sensorInfo): si.id=" << sm->id
<< " mb_initOK=" << i.reg->mb_initOK << endl; << " reg=" << ModbusRTU::dat2str(i.reg->mbreg)
<< " val=" << sm->value
<< " mb_initOK=" << i.reg->mb_initOK << endl;
if( !i.reg->mb_initOK ) if( !i.reg->mb_initOK )
continue; continue;
i.value = sm->value; i.value = sm->value;
updateRSProperty( &i, true ); updateRSProperty( &i, true );
return; return;
}
} }
} }
} }
...@@ -3022,54 +3040,62 @@ bool MBExchange::poll() ...@@ -3022,54 +3040,62 @@ bool MBExchange::poll()
ncycle++; ncycle++;
bool allNotRespond = true; bool allNotRespond = true;
for( auto it1 = rmap.begin(); it1 != rmap.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
RTUDevice* d(it1->second); auto d(it1->second);
if( d->mode_id != DefaultObjectId && d->mode == emSkipExchange ) if( d->mode_id != DefaultObjectId && d->mode == emSkipExchange )
continue; continue;
mblog3 << myname << "(poll): ask addr=" << ModbusRTU::addr2str(d->mbaddr) mblog3 << myname << "(poll): ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " regs=" << d->regmap.size() << endl; << " regs=" << d->pollmap.size() << endl;
d->prev_numreply.store(d->numreply); d->prev_numreply.store(d->numreply);
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it ) for( auto&& m: d->pollmap )
{ {
if( !checkProcActive() ) if( m.first>1 && (ncycle % m.first) != 0 )
return false;
if( exchangeMode == emSkipExchange )
continue; continue;
try auto&& regmap = m.second;
for( auto it = regmap->begin(); it != regmap->end(); ++it )
{ {
if( d->dtype == MBExchange::dtRTU || d->dtype == MBExchange::dtMTR ) if( !checkProcActive() )
return false;
if( exchangeMode == emSkipExchange )
continue;
try
{ {
if( pollRTU(d, it) ) if( d->dtype == MBExchange::dtRTU || d->dtype == MBExchange::dtMTR )
{ {
d->numreply++; if( pollRTU(d, it) )
allNotRespond = false; {
d->numreply++;
allNotRespond = false;
}
} }
} }
} catch( ModbusRTU::mbException& ex )
catch( ModbusRTU::mbException& ex ) {
{ mblog3 << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr)
mblog3 << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr) << " reg=" << ModbusRTU::dat2str(it->second->mbreg)
<< " reg=" << ModbusRTU::dat2str(it->second->mbreg) << " for sensors: ";
<< " for sensors: "; print_plist(mblog->level3(), it->second->slst)
print_plist(mblog->level3(), it->second->slst) << endl << " err: " << ex << endl;
<< endl << " err: " << ex << endl;
if( ex.err == ModbusRTU::erTimeOut && !d->ask_every_reg )
break;
}
if( ex.err == ModbusRTU::erTimeOut && !d->ask_every_reg ) if( it == regmap->end() )
break; break;
}
if( it == d->regmap.end() )
break;
if( !checkProcActive() ) if( !checkProcActive() )
return false; return false;
}
} }
if( stat_time > 0 ) if( stat_time > 0 )
...@@ -3134,11 +3160,11 @@ bool MBExchange::RTUDevice::checkRespond( std::shared_ptr<DebugStream>& mblog ) ...@@ -3134,11 +3160,11 @@ bool MBExchange::RTUDevice::checkRespond( std::shared_ptr<DebugStream>& mblog )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::updateRespondSensors() void MBExchange::updateRespondSensors()
{ {
for( const auto& it1 : rmap ) for( const auto& it1 : devices )
{ {
RTUDevice* d(it1.second); auto d(it1.second);
if( d->resp_id != DefaultObjectId && (d->checkRespond(mblog) || d->resp_ptInit.checkTime()) ) if( d->resp_id != DefaultObjectId && (d->checkRespond(mblog) || d->resp_force || d->resp_ptInit.checkTime()) )
{ {
try try
{ {
...@@ -3231,8 +3257,28 @@ UniSetTypes::SimpleInfo* MBExchange::getInfo() ...@@ -3231,8 +3257,28 @@ UniSetTypes::SimpleInfo* MBExchange::getInfo()
inf << i->info << endl; inf << i->info << endl;
inf << vmon.pretty_str() << endl; inf << vmon.pretty_str() << endl;
inf << "LogServer: " << logserv_host << ":" << logserv_port << endl; inf << "LogServer: " << logserv_host << ":" << logserv_port << endl;
inf << "Devices:" << endl;
for( const auto& it : devices )
inf << " " << it.second->getShortInfo() << endl;
i->info = inf.str().c_str(); i->info = inf.str().c_str();
return i._retn(); return i._retn();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
std::string MBExchange::RTUDevice::getShortInfo() const
{
ostringstream s;
s << "mbaddr=" << ModbusRTU::addr2str(mbaddr) << ":"
<< " resp_state=" << resp_state
<< " (resp_id=" << resp_id << " resp_force=" << resp_force
<< " resp_invert=" << resp_invert
<< " numreply=" << numreply
<< " timeout=" << resp_Delay.getOnDelay()
<< " type=" << dtype
<< ")" << endl;
return std::move( s.str() );
}
// ----------------------------------------------------------------------------
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <map> #include <map>
#include <vector> #include <unordered_map>
#include <memory> #include <memory>
#include "IONotifyController.h" #include "IONotifyController.h"
#include "UniSetObject_LT.h" #include "UniSetObject_LT.h"
...@@ -84,7 +84,7 @@ class MBExchange: ...@@ -84,7 +84,7 @@ class MBExchange:
RSProperty(): RSProperty():
nbit(-1), vType(VTypes::vtUnknown), nbit(-1), vType(VTypes::vtUnknown),
rnum(VTypes::wsize(VTypes::vtUnknown)), rnum(VTypes::wsize(VTypes::vtUnknown)),
nbyte(0), reg(0) nbyte(0)
{} {}
// т.к. IOBase содержит rwmutex с запрещённым конструктором копирования // т.к. IOBase содержит rwmutex с запрещённым конструктором копирования
...@@ -94,7 +94,7 @@ class MBExchange: ...@@ -94,7 +94,7 @@ class MBExchange:
RSProperty( RSProperty&& r ) = default; RSProperty( RSProperty&& r ) = default;
RSProperty& operator=(RSProperty&& r) = default; RSProperty& operator=(RSProperty&& r) = default;
RegInfo* reg; std::shared_ptr<RegInfo> reg;
}; };
friend std::ostream& operator<<( std::ostream& os, const RSProperty& p ); friend std::ostream& operator<<( std::ostream& os, const RSProperty& p );
...@@ -102,7 +102,7 @@ class MBExchange: ...@@ -102,7 +102,7 @@ class MBExchange:
typedef std::list<RSProperty> PList; typedef std::list<RSProperty> PList;
static std::ostream& print_plist( std::ostream& os, const PList& p ); static std::ostream& print_plist( std::ostream& os, const PList& p );
typedef std::map<ModbusRTU::RegID, RegInfo*> RegMap; typedef std::map<ModbusRTU::RegID, std::shared_ptr<RegInfo>> RegMap;
struct RegInfo struct RegInfo
{ {
// т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования // т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования
...@@ -126,7 +126,7 @@ class MBExchange: ...@@ -126,7 +126,7 @@ class MBExchange:
PList slst; PList slst;
ModbusRTU::RegID id; ModbusRTU::RegID id;
RTUDevice* dev; std::shared_ptr<RTUDevice> dev;
// only for RTU188 // only for RTU188
RTUStorage::RTUJack rtuJack; RTUStorage::RTUJack rtuJack;
...@@ -151,11 +151,6 @@ class MBExchange: ...@@ -151,11 +151,6 @@ class MBExchange:
// Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров" // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
// ещё не инициализировано из SM // ещё не инициализировано из SM
bool sm_initOK; /*!< инициализировалось ли значение из SM */ bool sm_initOK; /*!< инициализировалось ли значение из SM */
/*! приоритет опроса, 0,1 - высший,
* 1...n - задаёт "часоту" опроса. Т.е. каждые 1...n циклов
*/
int pollfactor = { 0 };
}; };
friend std::ostream& operator<<( std::ostream& os, RegInfo& r ); friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
...@@ -164,7 +159,6 @@ class MBExchange: ...@@ -164,7 +159,6 @@ class MBExchange:
struct RTUDevice struct RTUDevice
{ {
RTUDevice(): RTUDevice():
respnond(false),
mbaddr(0), mbaddr(0),
dtype(dtUnknown), dtype(dtUnknown),
resp_id(UniSetTypes::DefaultObjectId), resp_id(UniSetTypes::DefaultObjectId),
...@@ -176,13 +170,12 @@ class MBExchange: ...@@ -176,13 +170,12 @@ class MBExchange:
mode_id(UniSetTypes::DefaultObjectId), mode_id(UniSetTypes::DefaultObjectId),
mode(emNone), mode(emNone),
speed(ComPort::ComSpeed38400), speed(ComPort::ComSpeed38400),
rtu(0) rtu188(0)
{ {
} }
bool respnond;
ModbusRTU::ModbusAddr mbaddr; /*!< адрес устройства */ ModbusRTU::ModbusAddr mbaddr; /*!< адрес устройства */
RegMap regmap; std::unordered_map<unsigned int, std::shared_ptr<RegMap>> pollmap;
DeviceType dtype; /*!< тип устройства */ DeviceType dtype; /*!< тип устройства */
...@@ -210,12 +203,14 @@ class MBExchange: ...@@ -210,12 +203,14 @@ class MBExchange:
// специфические поля для RS // специфические поля для RS
ComPort::Speed speed; ComPort::Speed speed;
RTUStorage* rtu; std::shared_ptr<RTUStorage> rtu188;
std::string getShortInfo() const;
}; };
friend std::ostream& operator<<( std::ostream& os, RTUDevice& d ); friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
typedef std::map<ModbusRTU::ModbusAddr, RTUDevice*> RTUDeviceMap; typedef std::map<ModbusRTU::ModbusAddr, std::shared_ptr<RTUDevice>> RTUDeviceMap;
friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d ); friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
void printMap(RTUDeviceMap& d); void printMap(RTUDeviceMap& d);
...@@ -256,14 +251,14 @@ class MBExchange: ...@@ -256,14 +251,14 @@ class MBExchange:
InitRegInfo(): InitRegInfo():
dev(0), mbreg(0), dev(0), mbreg(0),
mbfunc(ModbusRTU::fnUnknown), mbfunc(ModbusRTU::fnUnknown),
initOK(false), ri(0) initOK(false)
{} {}
RSProperty p; RSProperty p;
RTUDevice* dev; std::shared_ptr<RTUDevice> dev;
ModbusRTU::ModbusData mbreg; ModbusRTU::ModbusData mbreg;
ModbusRTU::SlaveFunctionCode mbfunc; ModbusRTU::SlaveFunctionCode mbfunc;
bool initOK; bool initOK;
RegInfo* ri; std::shared_ptr<RegInfo> ri;
}; };
typedef std::list<InitRegInfo> InitList; typedef std::list<InitRegInfo> InitList;
...@@ -272,14 +267,14 @@ class MBExchange: ...@@ -272,14 +267,14 @@ class MBExchange:
bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p ); bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p );
bool allInitOK; bool allInitOK;
RTUDeviceMap rmap; RTUDeviceMap devices;
InitList initRegList; /*!< список регистров для инициализации */ InitList initRegList; /*!< список регистров для инициализации */
UniSetTypes::uniset_rwmutex pollMutex; UniSetTypes::uniset_rwmutex pollMutex;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) = 0; virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) = 0;
virtual bool poll(); virtual bool poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it ); bool pollRTU( std::shared_ptr<RTUDevice>& dev, RegMap::iterator& it );
void updateSM(); void updateSM();
void updateRTU(RegMap::iterator& it); void updateRTU(RegMap::iterator& it);
...@@ -301,15 +296,15 @@ class MBExchange: ...@@ -301,15 +296,15 @@ class MBExchange:
void initDeviceList(); void initDeviceList();
void initOffsetList(); void initOffsetList();
RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it ); std::shared_ptr<RTUDevice> addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
RegInfo* addReg( RegMap& rmap, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, RTUDevice* dev ); std::shared_ptr<RegInfo> addReg(std::shared_ptr<RegMap>& devices, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, std::shared_ptr<RTUDevice> dev );
RSProperty* addProp( PList& plist, RSProperty&& p ); RSProperty* addProp( PList& plist, RSProperty&& p );
bool initMTRitem( UniXML::iterator& it, RegInfo* p ); bool initMTRitem(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
bool initRTU188item( UniXML::iterator& it, RegInfo* p ); bool initRTU188item(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
bool initRSProperty( RSProperty& p, UniXML::iterator& it ); bool initRSProperty( RSProperty& p, UniXML::iterator& it );
bool initRegInfo( RegInfo* r, UniXML::iterator& it, RTUDevice* dev ); bool initRegInfo(std::shared_ptr<RegInfo>& r, UniXML::iterator& it, std::shared_ptr<RTUDevice>& dev );
bool initRTUDevice( RTUDevice* d, UniXML::iterator& it ); bool initRTUDevice( std::shared_ptr<RTUDevice>& d, UniXML::iterator& it );
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it ); virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
std::string initPropPrefix( const std::string& def_prop_prefix = "" ); std::string initPropPrefix( const std::string& def_prop_prefix = "" );
...@@ -366,6 +361,8 @@ class MBExchange: ...@@ -366,6 +361,8 @@ class MBExchange:
PassiveTimer ptReopen; /*!< таймер для переоткрытия соединения */ PassiveTimer ptReopen; /*!< таймер для переоткрытия соединения */
Trigger trReopen; Trigger trReopen;
PassiveTimer ptInitChannel; /*!< таймер не реинициализацию канала связи */
// т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список // т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список
// и отдельно его проверяем потом // и отдельно его проверяем потом
typedef std::list<IOBase> ThresholdList; typedef std::list<IOBase> ThresholdList;
......
...@@ -48,7 +48,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm ...@@ -48,7 +48,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
if( shm->isLocalwork() ) if( shm->isLocalwork() )
{ {
readConfiguration(); readConfiguration();
rtuQueryOptimization(rmap); rtuQueryOptimization(devices);
initDeviceList(); initDeviceList();
} }
else else
...@@ -58,7 +58,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm ...@@ -58,7 +58,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
pollThread->setFinalAction(this, &MBTCPMaster::final_thread); pollThread->setFinalAction(this, &MBTCPMaster::final_thread);
if( mblog->is_info() ) if( mblog->is_info() )
printMap(rmap); printMap(devices);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBTCPMaster::~MBTCPMaster() MBTCPMaster::~MBTCPMaster()
...@@ -81,6 +81,7 @@ std::shared_ptr<ModbusClient> MBTCPMaster::initMB( bool reopen ) ...@@ -81,6 +81,7 @@ std::shared_ptr<ModbusClient> MBTCPMaster::initMB( bool reopen )
mbtcp.reset(); mbtcp.reset();
mb.reset(); mb.reset();
ptInitChannel.reset();
} }
try try
...@@ -252,7 +253,7 @@ UniSetTypes::SimpleInfo* MBTCPMaster::getInfo() ...@@ -252,7 +253,7 @@ UniSetTypes::SimpleInfo* MBTCPMaster::getInfo()
ostringstream inf; ostringstream inf;
inf << i->info << endl; inf << i->info << endl;
inf << "poll: " << iaddr << ":" << port << endl; inf << "poll: " << iaddr << ":" << port << " pesrsistent-connection=" << ( force_disconnect ? "NO" : "YES" ) << endl;
i->info = inf.str().c_str(); i->info = inf.str().c_str();
return i._retn(); return i._retn();
......
...@@ -69,6 +69,9 @@ ...@@ -69,6 +69,9 @@
(после этого идёт попытка реинициализировать соединение) (после этого идёт попытка реинициализировать соединение)
По умолчанию 5000 мсек. По умолчанию 5000 мсек.
\b --xxx-reinit-timeout или \b reinit_timeout msec - таймаут на реинициализацию канала связи (после потери связи)
По умолчанию timeout.
\b --xxx-no-query-optimization или \b no_query_optimization - [1|0] отключить оптимизацию запросов \b --xxx-no-query-optimization или \b no_query_optimization - [1|0] отключить оптимизацию запросов
Оптимизация заключается в том, что регистры идущие подряд автоматически запрашиваются/записываются одним запросом. Оптимизация заключается в том, что регистры идущие подряд автоматически запрашиваются/записываются одним запросом.
......
...@@ -128,7 +128,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob ...@@ -128,7 +128,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
if( shm->isLocalwork() ) if( shm->isLocalwork() )
{ {
readConfiguration(); readConfiguration();
rtuQueryOptimization(rmap); rtuQueryOptimization(devices);
initDeviceList(); initDeviceList();
} }
else else
...@@ -145,7 +145,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob ...@@ -145,7 +145,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
ptReopen.setTiming(default_timeout); ptReopen.setTiming(default_timeout);
if( mblog->is_info() ) if( mblog->is_info() )
printMap(rmap); printMap(devices);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBTCPMultiMaster::~MBTCPMultiMaster() MBTCPMultiMaster::~MBTCPMultiMaster()
...@@ -171,6 +171,9 @@ MBTCPMultiMaster::~MBTCPMultiMaster() ...@@ -171,6 +171,9 @@ MBTCPMultiMaster::~MBTCPMultiMaster()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen ) std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen )
{ {
if( mb )
ptInitChannel.reset();
// просто движемся по кругу (т.к. связь не проверяется) // просто движемся по кругу (т.к. связь не проверяется)
// движемся в обратном порядке, т.к. сортировка по возрастанию приоритета // движемся в обратном порядке, т.к. сортировка по возрастанию приоритета
if( checktime <= 0 ) if( checktime <= 0 )
...@@ -363,17 +366,16 @@ void MBTCPMultiMaster::check_thread() ...@@ -363,17 +366,16 @@ void MBTCPMultiMaster::check_thread()
{ {
try try
{ {
if( it->use ) // игнорируем текущий mbtcp // Если use=1" связь не проверяем и считаем что связь есть..
continue; bool r = ( it->use ? true : it->check() );
bool r = it->check(); mblog4 << myname << "(check): " << it->myname << " " << ( r ? "OK" : "FAIL" ) << endl;
mbinfo << myname << "(check): " << it->myname << " " << ( r ? "OK" : "FAIL" ) << endl;
try try
{ {
if( it->respond_id != DefaultObjectId && (it->respond_force || !it->respond_init || r != it->respond) ) if( it->respond_id != DefaultObjectId && (it->respond_force || !it->respond_init || r != it->respond) )
{ {
bool set = it->respond_invert ? !it->respond : it->respond; bool set = it->respond_invert ? !r : r;
shm->localSetValue(it->respond_it, it->respond_id, (set ? 1 : 0), getId()); shm->localSetValue(it->respond_it, it->respond_id, (set ? 1 : 0), getId());
it->respond_init = true; it->respond_init = true;
} }
...@@ -413,7 +415,7 @@ void MBTCPMultiMaster::initIterators() ...@@ -413,7 +415,7 @@ void MBTCPMultiMaster::initIterators()
{ {
MBExchange::initIterators(); MBExchange::initIterators();
for( auto& it : mblist ) for( auto && it : mblist )
shm->initIterator(it.respond_it); shm->initIterator(it.respond_it);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -497,7 +499,13 @@ std::shared_ptr<MBTCPMultiMaster> MBTCPMultiMaster::init_mbmaster( int argc, con ...@@ -497,7 +499,13 @@ std::shared_ptr<MBTCPMultiMaster> MBTCPMultiMaster::init_mbmaster( int argc, con
const std::string MBTCPMultiMaster::MBSlaveInfo::getShortInfo() const const std::string MBTCPMultiMaster::MBSlaveInfo::getShortInfo() const
{ {
ostringstream s; ostringstream s;
s << myname << " respond=" << respond; s << myname << " respond=" << respond
<< " (respond_id=" << respond_id << " respond_invert=" << respond_invert
<< " recv_timeout=" << recv_timeout << " resp_force=" << respond_force
<< " use=" << use << " ignore=" << ignore << " priority=" << priority
<< " persistent-connection=" << !force_disconnect
<< ")";
return std::move(s.str()); return std::move(s.str());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -508,7 +516,7 @@ UniSetTypes::SimpleInfo* MBTCPMultiMaster::getInfo() ...@@ -508,7 +516,7 @@ UniSetTypes::SimpleInfo* MBTCPMultiMaster::getInfo()
ostringstream inf; ostringstream inf;
inf << i->info << endl; inf << i->info << endl;
inf << "Gates: " << endl; inf << "Gates: " << (checktime <= 0 ? "/ check connections DISABLED /" : "") << endl;
for( const auto& m : mblist ) for( const auto& m : mblist )
inf << " " << m.getShortInfo() << endl; inf << " " << m.getShortInfo() << endl;
......
...@@ -87,6 +87,9 @@ ...@@ -87,6 +87,9 @@
(после этого идёт попытка реинициализировать соединение) (после этого идёт попытка реинициализировать соединение)
По умолчанию 5000 мсек. По умолчанию 5000 мсек.
\b --xxx-reinit-timeout или \b reinit_timeout msec - таймаут на реинициализацию канала связи (после потери связи)
По умолчанию timeout мсек.
\b --xxx-no-query-optimization или \b no_query_optimization - [1|0] отключить оптимизацию запросов \b --xxx-no-query-optimization или \b no_query_optimization - [1|0] отключить оптимизацию запросов
Оптимизация заключается в том, что регистры идущие подряд автоматически запрашиваются/записываются одним запросом. Оптимизация заключается в том, что регистры идущие подряд автоматически запрашиваются/записываются одним запросом.
...@@ -280,6 +283,7 @@ class MBTCPMultiMaster: ...@@ -280,6 +283,7 @@ class MBTCPMultiMaster:
bool check(); bool check();
inline void setUse( bool st ) inline void setUse( bool st )
{ {
respond_init = !( st && !use );
use = st; use = st;
} }
......
...@@ -70,7 +70,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm ...@@ -70,7 +70,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
if( shm->isLocalwork() ) if( shm->isLocalwork() )
{ {
readConfiguration(); readConfiguration();
rtuQueryOptimization(rmap); rtuQueryOptimization(devices);
initDeviceList(); initDeviceList();
} }
else else
...@@ -79,7 +79,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm ...@@ -79,7 +79,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
initMB(false); initMB(false);
if( dlog()->is_info() ) if( dlog()->is_info() )
printMap(rmap); printMap(devices);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void RTUExchange::help_print( int argc, const char* const* argv ) void RTUExchange::help_print( int argc, const char* const* argv )
...@@ -204,9 +204,9 @@ bool RTUExchange::poll() ...@@ -204,9 +204,9 @@ bool RTUExchange::poll()
bool allNotRespond = true; bool allNotRespond = true;
ComPort::Speed s = mbrtu->getSpeed(); ComPort::Speed s = mbrtu->getSpeed();
for( auto it1 : rmap ) for( auto it1 : devices )
{ {
RTUDevice* d(it1.second); auto d = it1.second;
if( d->mode_id != DefaultObjectId && d->mode == emSkipExchange ) if( d->mode_id != DefaultObjectId && d->mode == emSkipExchange )
continue; continue;
...@@ -221,7 +221,7 @@ bool RTUExchange::poll() ...@@ -221,7 +221,7 @@ bool RTUExchange::poll()
if( d->dtype == MBExchange::dtRTU188 ) if( d->dtype == MBExchange::dtRTU188 )
{ {
if( !d->rtu ) if( !d->rtu188 )
continue; continue;
dlog3 << myname << "(pollRTU188): poll RTU188 " dlog3 << myname << "(pollRTU188): poll RTU188 "
...@@ -233,7 +233,7 @@ bool RTUExchange::poll() ...@@ -233,7 +233,7 @@ bool RTUExchange::poll()
if( rs_pre_clean ) if( rs_pre_clean )
mb->cleanupChannel(); mb->cleanupChannel();
d->rtu->poll(mbrtu); d->rtu188->poll(mbrtu);
d->numreply++; d->numreply++;
allNotRespond = false; allNotRespond = false;
} }
...@@ -249,38 +249,46 @@ bool RTUExchange::poll() ...@@ -249,38 +249,46 @@ bool RTUExchange::poll()
else else
{ {
dlog3 << myname << "(poll): ask addr=" << ModbusRTU::addr2str(d->mbaddr) dlog3 << myname << "(poll): ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " regs=" << d->regmap.size() << endl; << " regs=" << d->pollmap.size() << endl;
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it ) for( auto&& m: d->pollmap )
{ {
try if( m.first!=0 && (ncycle % m.first) != 0 )
continue;
auto rmap = m.second;
for( auto&& it = rmap->begin(); it != rmap->end(); ++it )
{ {
if( d->dtype == RTUExchange::dtRTU || d->dtype == RTUExchange::dtMTR ) try
{ {
if( rs_pre_clean ) if( d->dtype == RTUExchange::dtRTU || d->dtype == RTUExchange::dtMTR )
mb->cleanupChannel();
if( pollRTU(d, it) )
{ {
d->numreply++; if( rs_pre_clean )
allNotRespond = false; mb->cleanupChannel();
if( pollRTU(d, it) )
{
d->numreply++;
allNotRespond = false;
}
} }
} }
} catch( ModbusRTU::mbException& ex )
catch( ModbusRTU::mbException& ex ) {
{ dlog3 << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr)
dlog3 << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr) << " reg=" << ModbusRTU::dat2str(it->second->mbreg)
<< " reg=" << ModbusRTU::dat2str(it->second->mbreg) << " for sensors: ";
<< " for sensors: "; print_plist(dlog()->level3(), it->second->slst);
print_plist(dlog()->level3(), it->second->slst); dlog()->level3() << " err: " << ex << endl;
dlog()->level3() << " err: " << ex << endl; }
}
if( it == d->regmap.end() ) if( it == rmap->end() )
break; break;
if( !checkProcActive() ) if( !checkProcActive() )
return false; return false;
}
} }
} }
} }
......
...@@ -8,11 +8,13 @@ ...@@ -8,11 +8,13 @@
--mbtcp-set-prop-prefix \ --mbtcp-set-prop-prefix \
--mbtcp-filter-field rs \ --mbtcp-filter-field rs \
--mbtcp-filter-value 5 \ --mbtcp-filter-value 5 \
--mbtcp-recv-timeout 1000 \ --mbtcp-recv-timeout 7000 \
--mbtcp-timeout 2000 \ --mbtcp-timeout 2000 \
--mbtcp-polltime 1000 \ --mbtcp-polltime 2000 \
--mbtcp-force-out 1 \ --mbtcp-force-out 1 \
--mbtcp-log-add-levels any \ --mbtcp-log-add-levels any \
--mbtcp-persistent-connection 1 \
--mbtcp-run-logserver \
$* $*
#--mbtcp-exchange-mode-id MB1_Mode_AS \ #--mbtcp-exchange-mode-id MB1_Mode_AS \
......
...@@ -559,7 +559,7 @@ void MBSlave::execute_rtu() ...@@ -559,7 +559,7 @@ void MBSlave::execute_rtu()
} }
} }
for( auto& it : iomap ) for( auto && it : iomap )
IOBase::processingThreshold(&it.second, shm, force); IOBase::processingThreshold(&it.second, shm, force);
} }
catch(...) {} catch(...) {}
...@@ -645,7 +645,7 @@ void MBSlave::execute_tcp() ...@@ -645,7 +645,7 @@ void MBSlave::execute_tcp()
} }
} }
for( auto& it : iomap ) for( auto && it : iomap )
IOBase::processingThreshold(&it.second, shm, force); IOBase::processingThreshold(&it.second, shm, force);
} }
catch( const std::exception& ex ) catch( const std::exception& ex )
...@@ -759,9 +759,9 @@ void MBSlave::askSensors( UniversalIO::UIOCommand cmd ) ...@@ -759,9 +759,9 @@ void MBSlave::askSensors( UniversalIO::UIOCommand cmd )
if( force ) if( force )
return; return;
for( auto& it : iomap ) for( const auto& it : iomap )
{ {
IOProperty* p(&it.second); const IOProperty* p(&it.second);
try try
{ {
...@@ -1147,7 +1147,7 @@ int MBSlave::getOptimizeWriteFunction( const int fn ) ...@@ -1147,7 +1147,7 @@ int MBSlave::getOptimizeWriteFunction( const int fn )
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool MBSlave::BitRegProperty::check( const IOController_i::SensorInfo& si ) bool MBSlave::BitRegProperty::check( const IOController_i::SensorInfo& si )
{ {
for( auto& i : bvec ) for( const auto& i : bvec )
{ {
if( i.si.id == si.id && i.si.node == si.node ) if( i.si.id == si.id && i.si.node == si.node )
return true; return true;
...@@ -1267,7 +1267,7 @@ std::ostream& operator<<( std::ostream& os, MBSlave::BitRegProperty& p ) ...@@ -1267,7 +1267,7 @@ std::ostream& operator<<( std::ostream& os, MBSlave::BitRegProperty& p )
{ {
os << " reg=" << ModbusRTU::dat2str(p.mbreg) << "(" << (int)p.mbreg << ")[ "; os << " reg=" << ModbusRTU::dat2str(p.mbreg) << "(" << (int)p.mbreg << ")[ ";
for( auto& i : p.bvec ) for( const auto& i : p.bvec )
os << "'" << i.si.id << "' "; os << "'" << i.si.id << "' ";
os << "]"; os << "]";
...@@ -1906,36 +1906,39 @@ ModbusRTU::mbErrCode MBSlave::real_read_prop( IOProperty* p, ModbusRTU::ModbusDa ...@@ -1906,36 +1906,39 @@ ModbusRTU::mbErrCode MBSlave::real_read_prop( IOProperty* p, ModbusRTU::ModbusDa
else else
return ModbusRTU::erBadDataAddress; return ModbusRTU::erBadDataAddress;
mblog3 << myname << "(real_read_prop): read OK. sid=" << p->si.id << " val=" << val << endl;
pingOK = true; pingOK = true;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
catch( UniSetTypes::NameNotFound& ex ) catch( UniSetTypes::NameNotFound& ex )
{ {
mbwarn << myname << "(real_read_it): " << ex << endl; mbwarn << myname << "(real_read_prop): " << ex << endl;
return ModbusRTU::erBadDataAddress; return ModbusRTU::erBadDataAddress;
} }
catch( UniSetTypes::OutOfRange& ex ) catch( UniSetTypes::OutOfRange& ex )
{ {
mbwarn << myname << "(real_read_it): " << ex << endl; mbwarn << myname << "(real_read_prop): " << ex << endl;
return ModbusRTU::erBadDataValue; return ModbusRTU::erBadDataValue;
} }
catch( const Exception& ex ) catch( const Exception& ex )
{ {
if( pingOK ) if( pingOK )
mbcrit << myname << "(real_read_it): " << ex << endl; mbcrit << myname << "(real_read_prop): " << ex << endl;
} }
catch( const CORBA::SystemException& ex ) catch( const CORBA::SystemException& ex )
{ {
if( pingOK ) if( pingOK )
mbcrit << myname << "(real_read_it): CORBA::SystemException: " mbcrit << myname << "(real_read_prop): CORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch(...)
{ {
if( pingOK ) if( pingOK )
mbcrit << myname << "(real_read_it) catch ..." << endl; mbcrit << myname << "(real_read_prop) catch ..." << endl;
} }
mbwarn << myname << "(real_read_prop): read sid=" << p->si.id << " FAILED!!" << endl;
pingOK = false; pingOK = false;
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
...@@ -2249,6 +2252,8 @@ UniSetTypes::SimpleInfo* MBSlave::getInfo() ...@@ -2249,6 +2252,8 @@ UniSetTypes::SimpleInfo* MBSlave::getInfo()
inf << i->info << endl; inf << i->info << endl;
inf << vmon.pretty_str() << endl; inf << vmon.pretty_str() << endl;
inf << "LogServer: " << logserv_host << ":" << logserv_port << endl; inf << "LogServer: " << logserv_host << ":" << logserv_port << endl;
inf << " iomap=" << iomap.size() << endl;
inf << "Statistic: askCount=" << askCount << " pingOK=" << pingOK << endl;
i->info = inf.str().c_str(); i->info = inf.str().c_str();
return i._retn(); return i._retn();
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <sstream> #include <sstream>
#include "Exceptions.h" #include "Exceptions.h"
#include "Extensions.h" #include "Extensions.h"
#include "MBTCPMultiSlave.h" #include "MBTCPPersistentSlave.h"
#include "modbus/ModbusRTUSlaveSlot.h" #include "modbus/ModbusRTUSlaveSlot.h"
#include "modbus/ModbusTCPServerSlot.h" #include "modbus/ModbusTCPServerSlot.h"
#include "modbus/MBLogSugar.h" #include "modbus/MBLogSugar.h"
...@@ -12,7 +12,7 @@ using namespace UniSetTypes; ...@@ -12,7 +12,7 @@ using namespace UniSetTypes;
using namespace UniSetExtensions; using namespace UniSetExtensions;
using namespace ModbusRTU; using namespace ModbusRTU;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, const std::shared_ptr<SharedMemory> ic, const string& prefix ): MBTCPPersistentSlave::MBTCPPersistentSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, const std::shared_ptr<SharedMemory> ic, const string& prefix ):
MBSlave(objId, shmId, ic, prefix), MBSlave(objId, shmId, ic, prefix),
sesscount_id(DefaultObjectId) sesscount_id(DefaultObjectId)
{ {
...@@ -22,7 +22,7 @@ MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::Obje ...@@ -22,7 +22,7 @@ MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::Obje
cnode = conf->getNode(conf_name); cnode = conf->getNode(conf_name);
if( cnode == NULL ) if( cnode == NULL )
throw UniSetTypes::SystemError("(MBTCPMultiSlave): Not found conf-node for " + myname ); throw UniSetTypes::SystemError("(MBTCPPersistentSlave): Not found conf-node for " + myname );
UniXML::iterator it(cnode); UniXML::iterator it(cnode);
...@@ -31,18 +31,20 @@ MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::Obje ...@@ -31,18 +31,20 @@ MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::Obje
if( waitTimeout == 0 ) if( waitTimeout == 0 )
waitTimeout = 4000; waitTimeout = 4000;
ptUpdateInfo.setTiming(waitTimeout);
vmonit(waitTimeout); vmonit(waitTimeout);
sessTimeout = conf->getArgInt("--" + prefix + "-session-timeout", it.getProp("sessTimeout")); sessTimeout = conf->getArgInt("--" + prefix + "-session-timeout", it.getProp("sessTimeout"));
if( sessTimeout == 0 ) if( sessTimeout == 0 )
sessTimeout = 10000; sessTimeout = 2000;
vmonit(sessTimeout); vmonit(sessTimeout);
sessMaxNum = conf->getArgInt("--" + prefix + "-session-maxnum", it.getProp("sessMaxNum")); sessMaxNum = conf->getArgInt("--" + prefix + "-session-maxnum", it.getProp("sessMaxNum"));
if( sessMaxNum == 0 ) if( sessMaxNum == 0 )
sessMaxNum = 10; sessMaxNum = 3;
vmonit(sessMaxNum); vmonit(sessMaxNum);
...@@ -109,11 +111,11 @@ MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::Obje ...@@ -109,11 +111,11 @@ MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::Obje
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBTCPMultiSlave::~MBTCPMultiSlave() MBTCPPersistentSlave::~MBTCPPersistentSlave()
{ {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBTCPMultiSlave::help_print( int argc, const char* const* argv ) void MBTCPPersistentSlave::help_print( int argc, const char* const* argv )
{ {
MBSlave::help_print(argc, argv); MBSlave::help_print(argc, argv);
...@@ -124,7 +126,7 @@ void MBTCPMultiSlave::help_print( int argc, const char* const* argv ) ...@@ -124,7 +126,7 @@ void MBTCPMultiSlave::help_print( int argc, const char* const* argv )
cout << "--prefix-session-count-id id - Датчик для отслеживания текущего количества соединений." << endl; cout << "--prefix-session-count-id id - Датчик для отслеживания текущего количества соединений." << endl;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
std::shared_ptr<MBTCPMultiSlave> MBTCPMultiSlave::init_mbslave( int argc, const char* const* argv, UniSetTypes::ObjectId icID, std::shared_ptr<MBTCPPersistentSlave> MBTCPPersistentSlave::init_mbslave( int argc, const char* const* argv, UniSetTypes::ObjectId icID,
const std::shared_ptr<SharedMemory> ic, const string& prefix ) const std::shared_ptr<SharedMemory> ic, const string& prefix )
{ {
auto conf = uniset_conf(); auto conf = uniset_conf();
...@@ -147,10 +149,10 @@ std::shared_ptr<MBTCPMultiSlave> MBTCPMultiSlave::init_mbslave( int argc, const ...@@ -147,10 +149,10 @@ std::shared_ptr<MBTCPMultiSlave> MBTCPMultiSlave::init_mbslave( int argc, const
} }
dinfo << "(mbslave): name = " << name << "(" << ID << ")" << endl; dinfo << "(mbslave): name = " << name << "(" << ID << ")" << endl;
return make_shared<MBTCPMultiSlave>(ID, icID, ic, prefix); return make_shared<MBTCPPersistentSlave>(ID, icID, ic, prefix);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBTCPMultiSlave::execute_tcp() void MBTCPPersistentSlave::execute_tcp()
{ {
auto sslot = dynamic_pointer_cast<ModbusTCPServerSlot>(mbslot); auto sslot = dynamic_pointer_cast<ModbusTCPServerSlot>(mbslot);
...@@ -177,6 +179,13 @@ void MBTCPMultiSlave::execute_tcp() ...@@ -177,6 +179,13 @@ void MBTCPMultiSlave::execute_tcp()
{ {
sslot->waitQuery( addr, waitTimeout ); sslot->waitQuery( addr, waitTimeout );
// если слишком быстро обработали запрос
// то ничего не делаем..
if( !ptUpdateInfo.checkTime() )
continue;
ptUpdateInfo.reset();
// Обновляем информацию по соединениям // Обновляем информацию по соединениям
sess.clear(); sess.clear();
sslot->getSessions(sess); sslot->getSessions(sess);
...@@ -318,7 +327,7 @@ void MBTCPMultiSlave::execute_tcp() ...@@ -318,7 +327,7 @@ void MBTCPMultiSlave::execute_tcp()
mbinfo << myname << "(execute_tcp): thread stopped.." << endl; mbinfo << myname << "(execute_tcp): thread stopped.." << endl;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBTCPMultiSlave::initIterators() void MBTCPPersistentSlave::initIterators()
{ {
MBSlave::initIterators(); MBSlave::initIterators();
...@@ -328,7 +337,7 @@ void MBTCPMultiSlave::initIterators() ...@@ -328,7 +337,7 @@ void MBTCPMultiSlave::initIterators()
i.second.initIterators(shm); i.second.initIterators(shm);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool MBTCPMultiSlave::deactivateObject() bool MBTCPPersistentSlave::deactivateObject()
{ {
if( mbslot ) if( mbslot )
{ {
...@@ -341,7 +350,7 @@ bool MBTCPMultiSlave::deactivateObject() ...@@ -341,7 +350,7 @@ bool MBTCPMultiSlave::deactivateObject()
return MBSlave::deactivateObject(); return MBSlave::deactivateObject();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBTCPMultiSlave::sigterm( int signo ) void MBTCPPersistentSlave::sigterm( int signo )
{ {
if( mbslot ) if( mbslot )
{ {
...@@ -354,7 +363,7 @@ void MBTCPMultiSlave::sigterm( int signo ) ...@@ -354,7 +363,7 @@ void MBTCPMultiSlave::sigterm( int signo )
MBSlave::sigterm(signo); MBSlave::sigterm(signo);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const std::string MBTCPMultiSlave::ClientInfo::getShortInfo() const const std::string MBTCPPersistentSlave::ClientInfo::getShortInfo() const
{ {
ostringstream s; ostringstream s;
...@@ -363,7 +372,7 @@ const std::string MBTCPMultiSlave::ClientInfo::getShortInfo() const ...@@ -363,7 +372,7 @@ const std::string MBTCPMultiSlave::ClientInfo::getShortInfo() const
return std::move(s.str()); return std::move(s.str());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
UniSetTypes::SimpleInfo* MBTCPMultiSlave::getInfo() UniSetTypes::SimpleInfo* MBTCPPersistentSlave::getInfo()
{ {
UniSetTypes::SimpleInfo_var i = MBSlave::getInfo(); UniSetTypes::SimpleInfo_var i = MBSlave::getInfo();
......
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#ifndef _MBTCPMultiSlave_H_ #ifndef _MBTCPPersistentSlave_H_
#define _MBTCPMultiSlave_H_ #define _MBTCPPersistentSlave_H_
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <unordered_map> #include <unordered_map>
#include "MBSlave.h" #include "MBSlave.h"
#include "modbus/ModbusTCPServer.h" #include "modbus/ModbusTCPServer.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/*! /*!
<MBTCPMultiSlave ....sesscount=""> <MBTCPPersistentSlave ....sesscount="">
<clients> <clients>
<item ip="" respond="" invert="1" askcount=""/> <item ip="" respond="" invert="1" askcount=""/>
<item ip="" respond="" invert="1" askcount=""/> <item ip="" respond="" invert="1" askcount=""/>
<item ip="" respond="" invert="1" askcount=""/> <item ip="" respond="" invert="1" askcount=""/>
</clients> </clients>
</MBTCPMultiSlave> </MBTCPPersistentSlave>
*/ */
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/*! Реализация многоптоточного slave-интерфейса */ /*! Реализация многоптоточного slave-интерфейса */
class MBTCPMultiSlave: class MBTCPPersistentSlave:
public MBSlave public MBSlave
{ {
public: public:
MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, const std::shared_ptr<SharedMemory> ic = nullptr, const std::string& prefix = "mbs" ); MBTCPPersistentSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, const std::shared_ptr<SharedMemory> ic = nullptr, const std::string& prefix = "mbs" );
virtual ~MBTCPMultiSlave(); virtual ~MBTCPPersistentSlave();
/*! глобальная функция для инициализации объекта */ /*! глобальная функция для инициализации объекта */
static std::shared_ptr<MBTCPMultiSlave> init_mbslave( int argc, const char* const* argv, static std::shared_ptr<MBTCPPersistentSlave> init_mbslave( int argc, const char* const* argv,
UniSetTypes::ObjectId shmID, const std::shared_ptr<SharedMemory> ic = nullptr, UniSetTypes::ObjectId shmID, const std::shared_ptr<SharedMemory> ic = nullptr,
const std::string& prefix = "mbs" ); const std::string& prefix = "mbs" );
...@@ -44,6 +44,7 @@ class MBTCPMultiSlave: ...@@ -44,6 +44,7 @@ class MBTCPMultiSlave:
timeout_t waitTimeout; timeout_t waitTimeout;
ModbusTCPServer::Sessions sess; /*!< список открытых сессий */ ModbusTCPServer::Sessions sess; /*!< список открытых сессий */
unsigned int sessMaxNum; unsigned int sessMaxNum;
PassiveTimer ptUpdateInfo;
struct ClientInfo struct ClientInfo
{ {
...@@ -82,5 +83,5 @@ class MBTCPMultiSlave: ...@@ -82,5 +83,5 @@ class MBTCPMultiSlave:
IOController::IOStateList::iterator sesscount_it; IOController::IOStateList::iterator sesscount_it;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#endif // _MBTCPMultiSlave_H_ #endif // _MBTCPPersistentSlave_H_
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bin_PROGRAMS = @PACKAGE@-mbslave @PACKAGE@-mbtcp-multislave bin_PROGRAMS = @PACKAGE@-mbslave @PACKAGE@-mbtcp-persistentslave
# не забывайте править версию в2.pc-файле # не забывайте править версию в2.pc-файле
UMBS_VER=@LIBVER@ UMBS_VER=@LIBVER@
...@@ -10,7 +10,7 @@ libUniSet2MBSlave_la_LIBADD = $(top_builddir)/lib/libUniSet2.la \ ...@@ -10,7 +10,7 @@ libUniSet2MBSlave_la_LIBADD = $(top_builddir)/lib/libUniSet2.la \
$(top_builddir)/extensions/lib/libUniSet2Extensions.la \ $(top_builddir)/extensions/lib/libUniSet2Extensions.la \
$(SIGC_LIBS) $(COMCPP_LIBS) $(SIGC_LIBS) $(COMCPP_LIBS)
libUniSet2MBSlave_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS) libUniSet2MBSlave_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libUniSet2MBSlave_la_SOURCES = MBSlave.cc MBTCPMultiSlave.cc libUniSet2MBSlave_la_SOURCES = MBSlave.cc MBTCPPersistentSlave.cc
@PACKAGE@_mbslave_SOURCES = mbslave.cc @PACKAGE@_mbslave_SOURCES = mbslave.cc
@PACKAGE@_mbslave_LDADD = libUniSet2MBSlave.la $(top_builddir)/lib/libUniSet2.la \ @PACKAGE@_mbslave_LDADD = libUniSet2MBSlave.la $(top_builddir)/lib/libUniSet2.la \
...@@ -19,12 +19,12 @@ libUniSet2MBSlave_la_SOURCES = MBSlave.cc MBTCPMultiSlave.cc ...@@ -19,12 +19,12 @@ libUniSet2MBSlave_la_SOURCES = MBSlave.cc MBTCPMultiSlave.cc
$(SIGC_LIBS) $(COMCPP_LIBS) $(SIGC_LIBS) $(COMCPP_LIBS)
@PACKAGE@_mbslave_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS) @PACKAGE@_mbslave_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
@PACKAGE@_mbtcp_multislave_SOURCES = mbtcp-multislave.cc @PACKAGE@_mbtcp_persistentslave_SOURCES = mbtcp-persistentslave.cc
@PACKAGE@_mbtcp_multislave_LDADD = libUniSet2MBSlave.la $(top_builddir)/lib/libUniSet2.la \ @PACKAGE@_mbtcp_persistentslave_LDADD = libUniSet2MBSlave.la $(top_builddir)/lib/libUniSet2.la \
$(top_builddir)/extensions/SharedMemory/libUniSet2SharedMemory.la \ $(top_builddir)/extensions/SharedMemory/libUniSet2SharedMemory.la \
$(top_builddir)/extensions/lib/libUniSet2Extensions.la \ $(top_builddir)/extensions/lib/libUniSet2Extensions.la \
$(SIGC_LIBS) $(COMCPP_LIBS) $(SIGC_LIBS) $(COMCPP_LIBS)
@PACKAGE@_mbtcp_multislave_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS) @PACKAGE@_mbtcp_persistentslave_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
# install # install
devel_include_HEADERS = *.h devel_include_HEADERS = *.h
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <cc++/socket.h> #include <cc++/socket.h>
#include "MBTCPMultiSlave.h" #include "MBTCPPersistentSlave.h"
#include "Configuration.h" #include "Configuration.h"
#include "Debug.h" #include "Debug.h"
#include "UniSetActivator.h" #include "UniSetActivator.h"
...@@ -56,7 +56,7 @@ int main(int argc, const char** argv) ...@@ -56,7 +56,7 @@ int main(int argc, const char** argv)
return 1; return 1;
} }
auto s = MBTCPMultiSlave::init_mbslave(argc, argv, shmID); auto s = MBTCPPersistentSlave::init_mbslave(argc, argv, shmID);
if( !s ) if( !s )
{ {
...@@ -70,9 +70,9 @@ int main(int argc, const char** argv) ...@@ -70,9 +70,9 @@ int main(int argc, const char** argv)
act->broadcast( sm.transport_msg() ); act->broadcast( sm.transport_msg() );
ulogany << "\n\n\n"; ulogany << "\n\n\n";
ulogany << "(main): -------------- MBTCPMultiSlave START -------------------------\n\n"; ulogany << "(main): -------------- MBTCPPersistentSlave START -------------------------\n\n";
dlogany << "\n\n\n"; dlogany << "\n\n\n";
dlogany << "(main): -------------- MBTCPMultiSlave START -------------------------\n\n"; dlogany << "(main): -------------- MBTCPPersistentSlave START -------------------------\n\n";
act->run(false); act->run(false);
return 0; return 0;
......
#!/bin/sh #!/bin/sh
uniset2-start.sh -f ./uniset2-mbtcp-multislave --confile test.xml --dlog-add-levels level3,level4 \ uniset2-start.sh -f ./uniset2-mbtcp-persistentslave --confile test.xml --dlog-add-levels level3,level4 \
--smemory-id SharedMemory \ --smemory-id SharedMemory \
--mbs-name MBMultiSlave1 --mbs-type TCP --mbs-inet-addr 127.0.0.1 --mbs-inet-port 2048 --mbs-reg-from-id 1 --mbs-my-addr 0x01 \ --mbs-name MBMultiSlave1 --mbs-type TCP --mbs-inet-addr 127.0.0.1 --mbs-inet-port 2048 --mbs-reg-from-id 1 --mbs-my-addr 0x01 \
$* $*
......
...@@ -289,7 +289,7 @@ bool SharedMemory::activateObject() ...@@ -289,7 +289,7 @@ bool SharedMemory::activateObject()
itPulsar = myioEnd(); itPulsar = myioEnd();
for( auto& it : hist ) for( auto && it : hist )
{ {
for( auto && hit : it.hlst ) for( auto && hit : it.hlst )
hit.ioit = myioEnd(); hit.ioit = myioEnd();
...@@ -331,7 +331,7 @@ void SharedMemory::checkHeartBeat() ...@@ -331,7 +331,7 @@ void SharedMemory::checkHeartBeat()
bool wdtpingOK = true; bool wdtpingOK = true;
for( auto& it : hlist ) for( auto && it : hlist )
{ {
try try
{ {
...@@ -378,7 +378,7 @@ void SharedMemory::checkHeartBeat() ...@@ -378,7 +378,7 @@ void SharedMemory::checkHeartBeat()
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool SharedMemory::readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec ) bool SharedMemory::readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec )
{ {
for( auto& r : lstRSlot ) for( auto && r : lstRSlot )
{ {
try try
{ {
...@@ -666,7 +666,7 @@ void SharedMemory::buildHistoryList( xmlNode* cnode ) ...@@ -666,7 +666,7 @@ void SharedMemory::buildHistoryList( xmlNode* cnode )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void SharedMemory::checkHistoryFilter( UniXML::iterator& xit ) void SharedMemory::checkHistoryFilter( UniXML::iterator& xit )
{ {
for( auto& it : hist ) for( auto && it : hist )
{ {
if( xit.getProp(it.filter).empty() ) if( xit.getProp(it.filter).empty() )
continue; continue;
...@@ -701,9 +701,9 @@ void SharedMemory::saveHistory() ...@@ -701,9 +701,9 @@ void SharedMemory::saveHistory()
if( hist.empty() ) if( hist.empty() )
return; return;
for( auto& it : hist ) for( auto && it : hist )
{ {
for( auto& hit : it.hlst ) for( auto && hit : it.hlst )
{ {
try try
{ {
...@@ -743,7 +743,7 @@ void SharedMemory::updateHistory( std::shared_ptr<USensorInfo>& s_it, IOControll ...@@ -743,7 +743,7 @@ void SharedMemory::updateHistory( std::shared_ptr<USensorInfo>& s_it, IOControll
<< " value=" << value << " value=" << value
<< endl; << endl;
for( auto& it1 : i->second ) for( auto && it1 : i->second )
{ {
History::iterator it = it1; History::iterator it = it1;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "Extensions.h" #include "Extensions.h"
#include "RTUExchange.h" #include "RTUExchange.h"
#include "MBSlave.h" #include "MBSlave.h"
#include "MBTCPMultiSlave.h" #include "MBTCPPersistentSlave.h"
#include "MBTCPMaster.h" #include "MBTCPMaster.h"
#include "SharedMemory.h" #include "SharedMemory.h"
//#include "UniExchange.h" //#include "UniExchange.h"
...@@ -215,7 +215,7 @@ int main( int argc, const char** argv ) ...@@ -215,7 +215,7 @@ int main( int argc, const char** argv )
dinfo << "(smemory-plus): add MBTCPMultiSlave(" << p.str() << ")" << endl; dinfo << "(smemory-plus): add MBTCPMultiSlave(" << p.str() << ")" << endl;
auto mbs = MBTCPMultiSlave::init_mbslave(argc, argv, shm->getId(), shm, p.str()); auto mbs = MBTCPPersistentSlave::init_mbslave(argc, argv, shm->getId(), shm, p.str());
if( !mbs ) if( !mbs )
return 1; return 1;
......
...@@ -430,7 +430,7 @@ bool UNetExchange::checkExistUNetHost( const std::string& addr, ost::tpport_t po ...@@ -430,7 +430,7 @@ bool UNetExchange::checkExistUNetHost( const std::string& addr, ost::tpport_t po
{ {
ost::IPV4Address a1(addr.c_str()); ost::IPV4Address a1(addr.c_str());
for( auto& it : recvlist ) for( const auto& it : recvlist )
{ {
if( it.r1->getAddress() == a1.getAddress() && it.r1->getPort() == port ) if( it.r1->getAddress() == a1.getAddress() && it.r1->getPort() == port )
return true; return true;
...@@ -441,7 +441,7 @@ bool UNetExchange::checkExistUNetHost( const std::string& addr, ost::tpport_t po ...@@ -441,7 +441,7 @@ bool UNetExchange::checkExistUNetHost( const std::string& addr, ost::tpport_t po
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UNetExchange::startReceivers() void UNetExchange::startReceivers()
{ {
for( auto& it : recvlist ) for( const auto& it : recvlist )
{ {
if( it.r1 ) if( it.r1 )
it.r1->start(); it.r1->start();
...@@ -701,7 +701,7 @@ void UNetExchange::sigterm( int signo ) ...@@ -701,7 +701,7 @@ void UNetExchange::sigterm( int signo )
unetinfo << myname << ": ********* SIGTERM(" << signo << ") ********" << endl; unetinfo << myname << ": ********* SIGTERM(" << signo << ") ********" << endl;
activated = false; activated = false;
for( auto& it : recvlist ) for( const auto& it : recvlist )
{ {
try try
{ {
...@@ -745,7 +745,7 @@ void UNetExchange::initIterators() ...@@ -745,7 +745,7 @@ void UNetExchange::initIterators()
if( sender2 ) if( sender2 )
sender2->initIterators(); sender2->initIterators();
for( auto& it : recvlist ) for( auto && it : recvlist )
it.initIterators(shm); it.initIterators(shm);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -814,7 +814,7 @@ std::shared_ptr<UNetExchange> UNetExchange::init_unetexchange( int argc, const c ...@@ -814,7 +814,7 @@ std::shared_ptr<UNetExchange> UNetExchange::init_unetexchange( int argc, const c
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UNetExchange::receiverEvent( const shared_ptr<UNetReceiver>& r, UNetReceiver::Event ev ) void UNetExchange::receiverEvent( const shared_ptr<UNetReceiver>& r, UNetReceiver::Event ev )
{ {
for( auto& it : recvlist ) for( auto && it : recvlist )
{ {
if( it.r1 == r ) if( it.r1 == r )
{ {
......
...@@ -285,8 +285,8 @@ void UNetReceiver::real_update() ...@@ -285,8 +285,8 @@ void UNetReceiver::real_update()
if( sub >= maxDifferens ) if( sub >= maxDifferens )
{ {
// считаем сколько пакетов потеряли.. // считаем сколько пакетов потеряли.. (pnum=0 - означает что мы только что запустились...)
if( p.num > pnum ) if( pnum != 0 && p.num > pnum )
{ {
lostPackets += sub; lostPackets += sub;
unetwarn << myname << "(update): sub=" << sub << " > maxDifferenst(" << maxDifferens << ")! lost " << sub << " packets " << endl; unetwarn << myname << "(update): sub=" << sub << " > maxDifferenst(" << maxDifferens << ")! lost " << sub << " packets " << endl;
......
...@@ -550,14 +550,28 @@ bool IOBase::initItem( IOBase* b, UniXML::iterator& it, const std::shared_ptr<SM ...@@ -550,14 +550,28 @@ bool IOBase::initItem( IOBase* b, UniXML::iterator& it, const std::shared_ptr<SM
b->breaklim = initIntProp(it, "breaklim", prefix, init_prefix_only); b->breaklim = initIntProp(it, "breaklim", prefix, init_prefix_only);
b->rawdata = initIntProp(it, "rawdata", prefix, init_prefix_only); b->rawdata = initIntProp(it, "rawdata", prefix, init_prefix_only);
long msec = initIntProp(it, "debouncedelay", prefix, init_prefix_only, UniSetTimer::WaitUpTime); long d_msec = initIntProp(it, "debouncedelay", prefix, init_prefix_only, UniSetTimer::WaitUpTime);
b->ptDebounce.setTiming(msec); b->ptDebounce.setTiming(d_msec);
msec = initIntProp(it, "ondelay", prefix, init_prefix_only, UniSetTimer::WaitUpTime); long d_on_msec = initIntProp(it, "ondelay", prefix, init_prefix_only, UniSetTimer::WaitUpTime);
b->ptOnDelay.setTiming(msec); b->ptOnDelay.setTiming(d_on_msec);
long d_off_msec = initIntProp(it, "offdelay", prefix, init_prefix_only, UniSetTimer::WaitUpTime);
b->ptOffDelay.setTiming(d_off_msec);
if( dlog && d_msec != UniSetTimer::WaitUpTime
&& d_on_msec != UniSetTimer::WaitUpTime
&& d_off_msec != UniSetTimer::WaitUpTime )
{
dlog->warn() << myname <<"(IOBase::readItem): "
<< " 'debouncedelay' is used in conjunction with the 'ondelay' and 'offdelay'. Sure?"
<< " [ debouncedelay=" << d_msec
<< " ondelay=" << d_on_msec
<< " offdelay=" << d_off_msec
<< " ]" << endl;
}
msec = initIntProp(it, "offdelay", prefix, init_prefix_only, UniSetTimer::WaitUpTime);
b->ptOffDelay.setTiming(msec);
b->front = false; b->front = false;
std::string front_t( initProp(it, "iofront", prefix, init_prefix_only) ); std::string front_t( initProp(it, "iofront", prefix, init_prefix_only) );
......
...@@ -125,16 +125,16 @@ class DelayTimer ...@@ -125,16 +125,16 @@ class DelayTimer
return check(prevState); return check(prevState);
} }
inline timeout_t getOnDelay() inline timeout_t getOnDelay() const
{ {
return onDelay; return onDelay;
} }
inline timeout_t getOffDelay() inline timeout_t getOffDelay() const
{ {
return offDelay; return offDelay;
} }
inline timeout_t getCurrent() inline timeout_t getCurrent() const
{ {
return pt.getCurrent(); return pt.getCurrent();
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define LogReader_H_ #define LogReader_H_
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
#include <string> #include <string>
#include <memory>
#include <queue> #include <queue>
#include <vector> #include <vector>
#include <cc++/socket.h> #include <cc++/socket.h>
...@@ -73,7 +74,7 @@ class LogReader ...@@ -73,7 +74,7 @@ class LogReader
timeout_t reconDelay; timeout_t reconDelay;
private: private:
UTCPStream* tcp; std::shared_ptr<UTCPStream> tcp;
std::string iaddr; std::string iaddr;
ost::tpport_t port; ost::tpport_t port;
bool cmdonly; bool cmdonly;
......
...@@ -113,7 +113,7 @@ class LogServer ...@@ -113,7 +113,7 @@ class LogServer
DebugStream mylog; DebugStream mylog;
std::shared_ptr< ThreadCreator<LogServer> > thr; std::shared_ptr< ThreadCreator<LogServer> > thr;
ost::TCPSocket* tcp; std::shared_ptr<ost::TCPSocket> tcp;
std::shared_ptr<DebugStream> elog; std::shared_ptr<DebugStream> elog;
std::shared_ptr<NullLogSession> nullsess; std::shared_ptr<NullLogSession> nullsess;
}; };
......
...@@ -70,6 +70,8 @@ class LogSession: ...@@ -70,6 +70,8 @@ class LogSession:
std::shared_ptr<LogAgregator> alog; std::shared_ptr<LogAgregator> alog;
sigc::connection conn; sigc::connection conn;
std::shared_ptr<LogSession> myptr;
// PassiveTimer ptSessionTimeout; // PassiveTimer ptSessionTimeout;
FinalSlot slFin; FinalSlot slFin;
std::atomic_bool cancelled; std::atomic_bool cancelled;
......
...@@ -46,8 +46,8 @@ class UniSetTimer ...@@ -46,8 +46,8 @@ class UniSetTimer
virtual timeout_t setTiming( timeout_t msec ) = 0; /*!< установить таймер и запустить */ virtual timeout_t setTiming( timeout_t msec ) = 0; /*!< установить таймер и запустить */
virtual void reset() = 0; /*!< перезапустить таймер */ virtual void reset() = 0; /*!< перезапустить таймер */
virtual timeout_t getCurrent() = 0; /*!< получить текущее значение таймера */ virtual timeout_t getCurrent() const = 0; /*!< получить текущее значение таймера */
virtual timeout_t getInterval() = 0; /*!< получить интервал, на который установлен таймер, в мс */ virtual timeout_t getInterval() const = 0; /*!< получить интервал, на который установлен таймер, в мс */
timeout_t getLeft(timeout_t timeout) /*!< получить время, которое остается от timeout после прошествия времени getCurrent() */ timeout_t getLeft(timeout_t timeout) /*!< получить время, которое остается от timeout после прошествия времени getCurrent() */
{ {
timeout_t ct = getCurrent(); timeout_t ct = getCurrent();
...@@ -104,8 +104,8 @@ class PassiveTimer: ...@@ -104,8 +104,8 @@ class PassiveTimer:
virtual timeout_t setTiming( timeout_t msec ); /*!< установить таймер и запустить. timeMS = 0 вызовет немедленное срабатывание */ virtual timeout_t setTiming( timeout_t msec ); /*!< установить таймер и запустить. timeMS = 0 вызовет немедленное срабатывание */
virtual void reset(); /*!< перезапустить таймер */ virtual void reset(); /*!< перезапустить таймер */
virtual timeout_t getCurrent(); /*!< получить текущее значение таймера, в мс */ virtual timeout_t getCurrent() const override; /*!< получить текущее значение таймера, в мс */
virtual timeout_t getInterval() /*!< получить интервал, на который установлен таймер, в мс */ virtual timeout_t getInterval() const override /*!< получить интервал, на который установлен таймер, в мс */
{ {
return (t_msec != UniSetTimer::WaitUpTime ? t_msec : 0); return (t_msec != UniSetTimer::WaitUpTime ? t_msec : 0);
} }
...@@ -113,7 +113,7 @@ class PassiveTimer: ...@@ -113,7 +113,7 @@ class PassiveTimer:
virtual void terminate(); /*!< прервать работу таймера */ virtual void terminate(); /*!< прервать работу таймера */
protected: protected:
timeout_t t_msec; /*!< интервал таймера, в милисекундах */ timeout_t t_msec = { 0 }; /*!< интервал таймера, в милисекундах */
std::chrono::high_resolution_clock::time_point t_start; /*!< время установки таймера (сброса) */ std::chrono::high_resolution_clock::time_point t_start; /*!< время установки таймера (сброса) */
private: private:
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#define Pulse_H_ #define Pulse_H_
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
#include <iostream> #include <iostream>
#include <algorithm>
#include "PassiveTimer.h" #include "PassiveTimer.h"
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
/*! Класс реализующий формирование импульсов заданной длительности(t1) и заданных пауз между ними(t0). /*! Класс реализующий формирование импульсов заданной длительности(t1) и заданных пауз между ними(t0).
...@@ -11,6 +12,8 @@ ...@@ -11,6 +12,8 @@
Формирование импульсов включается функцией run() либо функцией set(true). Формирование импульсов включается функцией run() либо функцией set(true).
Вызов reset() тоже включает формирование импульсов. Вызов reset() тоже включает формирование импульсов.
Выключается формирование вызовом set(false). Выключается формирование вызовом set(false).
\warning Точность поддержания "импульсов" зависит от частоты вызова step() или out()
*/ */
class Pulse class Pulse
{ {
...@@ -53,17 +56,13 @@ class Pulse ...@@ -53,17 +56,13 @@ class Pulse
if( ostate && t1.checkTime() ) if( ostate && t1.checkTime() )
{ {
ostate = false; ostate = false;
t0.setTiming(t0_msec);
// учитываем что step мог вызваться гораздо позже..
t0.setTiming( t0_msec - t1.getCurrent() % t1.getInterval() );
} }
if( !ostate && t0.checkTime() ) if( !ostate && t0.checkTime() )
{ {
ostate = true; ostate = true;
t1.setTiming(t1_msec);
// учитываем что step мог вызваться гораздо позже..
t1.setTiming(t1_msec - t0.getCurrent() % t0.getInterval() );
} }
return ostate; return ostate;
...@@ -102,9 +101,19 @@ class Pulse ...@@ -102,9 +101,19 @@ class Pulse
} }
inline long getT1()
{
return t1_msec;
}
inline long getT0()
{
return t0_msec;
}
protected: protected:
PassiveTimer t1; // таймер "1" PassiveTimer t1; // таймер "1"
PassiveTimer t0; // таймер "0" PassiveTimer t0; // таймер "0"
PassiveTimer tCorr; // корректирующий таймер
bool ostate; bool ostate;
bool isOn; bool isOn;
long t1_msec; long t1_msec;
......
...@@ -16,7 +16,7 @@ class UTCPStream: ...@@ -16,7 +16,7 @@ class UTCPStream:
void create( const std::string& hname, int port, bool throwflag = false, timeout_t timer = 0 ); void create( const std::string& hname, int port, bool throwflag = false, timeout_t timer = 0 );
// set keepalive params // set keepalive params
void setKeepAliveParams( timeout_t timeout_sec = 5, int conn_keepcnt = 1, int keepintvl=2 ); void setKeepAliveParams( timeout_t timeout_sec = 5, int conn_keepcnt = 1, int keepintvl = 2 );
protected: protected:
......
...@@ -40,6 +40,8 @@ class ModbusTCPSession: ...@@ -40,6 +40,8 @@ class ModbusTCPSession:
return caddr; return caddr;
} }
void setKeepAliveParams( timeout_t timeout_sec = 3, int conn_keepcnt = 2, int keepintvl = 2 );
protected: protected:
virtual void run(); virtual void run();
virtual void final(); virtual void final();
......
...@@ -41,7 +41,10 @@ int ModbusTCPMaster::getNextData( unsigned char* buf, int len ) ...@@ -41,7 +41,10 @@ int ModbusTCPMaster::getNextData( unsigned char* buf, int len )
void ModbusTCPMaster::setChannelTimeout( timeout_t msec ) void ModbusTCPMaster::setChannelTimeout( timeout_t msec )
{ {
if( tcp ) if( tcp )
{
tcp->setTimeout(msec); tcp->setTimeout(msec);
tcp->setKeepAliveParams((msec > 1000 ? msec / 1000 : 1));
}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
mbErrCode ModbusTCPMaster::sendData( unsigned char* buf, int len ) mbErrCode ModbusTCPMaster::sendData( unsigned char* buf, int len )
...@@ -186,12 +189,16 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -186,12 +189,16 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
ost::tpport_t port; ost::tpport_t port;
if( dlog->is_warn() ) if( dlog->is_warn() )
{
const char* err = tcp->getErrorString();
dlog->warn() << "(ModbusTCPMaster::query): ret=" << (int)ret dlog->warn() << "(ModbusTCPMaster::query): ret=" << (int)ret
<< " < rmh=" << (int)sizeof(rmh) << " < rmh=" << (int)sizeof(rmh)
<< " errnum: " << tcp->getErrorNumber() << " errnum: " << tcp->getErrorNumber()
<< " perr: " << tcp->getPeer(&port) << " perr: " << tcp->getPeer(&port)
<< " err: " << string(tcp->getErrorString()) << " err: " << (err ? string(err) : "")
<< endl; << endl;
}
disconnect(); disconnect();
return erTimeOut; // return erHardwareError; return erTimeOut; // return erHardwareError;
...@@ -306,7 +313,7 @@ bool ModbusTCPMaster::checkConnection( const std::string& ip, int port, int time ...@@ -306,7 +313,7 @@ bool ModbusTCPMaster::checkConnection( const std::string& ip, int port, int time
// Проверяем просто попыткой создать соединение.. // Проверяем просто попыткой создать соединение..
UTCPStream t; UTCPStream t;
t.create(ip, port, true, timeout_msec); t.create(ip, port, true, timeout_msec);
t.setKeepAliveParams( (timeout_msec > 1000 ? timeout_msec/1000 : 1),1,1); t.setKeepAliveParams( (timeout_msec > 1000 ? timeout_msec / 1000 : 1), 1, 1);
t.disconnect(); t.disconnect();
return true; return true;
} }
...@@ -333,7 +340,7 @@ void ModbusTCPMaster::reconnect() ...@@ -333,7 +340,7 @@ void ModbusTCPMaster::reconnect()
tcp = make_shared<UTCPStream>(); tcp = make_shared<UTCPStream>();
tcp->create(iaddr, port, true, 500); tcp->create(iaddr, port, true, 500);
tcp->setTimeout(replyTimeOut_ms); tcp->setTimeout(replyTimeOut_ms);
tcp->setKeepAliveParams((replyTimeOut_ms > 1000 ? replyTimeOut_ms/1000 : 1)); tcp->setKeepAliveParams((replyTimeOut_ms > 1000 ? replyTimeOut_ms / 1000 : 1));
} }
catch( const std::exception& e ) catch( const std::exception& e )
{ {
...@@ -387,7 +394,7 @@ void ModbusTCPMaster::connect( ost::InetAddress addr, int _port ) ...@@ -387,7 +394,7 @@ void ModbusTCPMaster::connect( ost::InetAddress addr, int _port )
tcp = make_shared<UTCPStream>(); tcp = make_shared<UTCPStream>();
tcp->create(iaddr, port, true, 500); tcp->create(iaddr, port, true, 500);
tcp->setTimeout(replyTimeOut_ms); tcp->setTimeout(replyTimeOut_ms);
tcp->setKeepAliveParams((replyTimeOut_ms > 1000 ? replyTimeOut_ms/1000 : 1)); tcp->setKeepAliveParams((replyTimeOut_ms > 1000 ? replyTimeOut_ms / 1000 : 1));
} }
catch( const std::exception& e ) catch( const std::exception& e )
{ {
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "modbus/ModbusTCPSession.h" #include "modbus/ModbusTCPSession.h"
#include "modbus/ModbusTCPCore.h" #include "modbus/ModbusTCPCore.h"
#include "UniSetTypes.h" #include "UniSetTypes.h"
// glibc..
#include <netinet/tcp.h>
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
using namespace std; using namespace std;
using namespace ModbusRTU; using namespace ModbusRTU;
...@@ -30,6 +32,14 @@ ModbusTCPSession::ModbusTCPSession( ost::TCPSocket& server, ModbusRTU::ModbusAdd ...@@ -30,6 +32,14 @@ ModbusTCPSession::ModbusTCPSession( ost::TCPSocket& server, ModbusRTU::ModbusAdd
askCount(0) askCount(0)
{ {
setCRCNoCheckit(true); setCRCNoCheckit(true);
timeout_t tout = timeout/1000;
if( tout <=0 )
tout = 3;
setKeepAlive(true);
setLinger(true);
setKeepAliveParams(tout);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
unsigned int ModbusTCPSession::getAskCount() unsigned int ModbusTCPSession::getAskCount()
...@@ -38,6 +48,16 @@ unsigned int ModbusTCPSession::getAskCount() ...@@ -38,6 +48,16 @@ unsigned int ModbusTCPSession::getAskCount()
return askCount; return askCount;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ModbusTCPSession::setKeepAliveParams( timeout_t timeout_sec, int keepcnt, int keepintvl )
{
SOCKET fd = TCPSession::so;
int enable = 1;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&enable, sizeof(enable));
setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void*) &keepcnt, sizeof(keepcnt));
setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void*) &keepintvl, sizeof (keepintvl));
setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void*) &timeout_sec, sizeof (timeout_sec));
}
// -------------------------------------------------------------------------
void ModbusTCPSession::run() void ModbusTCPSession::run()
{ {
if( cancelled ) if( cancelled )
...@@ -64,8 +84,16 @@ void ModbusTCPSession::run() ...@@ -64,8 +84,16 @@ void ModbusTCPSession::run()
ModbusRTU::mbErrCode res = erTimeOut; ModbusRTU::mbErrCode res = erTimeOut;
cancelled = false; cancelled = false;
char pbuf[3];
while( !cancelled && isPending(Socket::pendingInput, timeout) ) while( !cancelled && isPending(Socket::pendingInput, timeout) )
{ {
ssize_t n = peek( pbuf, sizeof(pbuf) );
// кажется сервер закрыл канал
if( n == 0 )
break;
res = receive(addr, timeout); res = receive(addr, timeout);
if( res == erSessionClosed ) if( res == erSessionClosed )
......
...@@ -60,7 +60,7 @@ void TCPCheck::check_thread() ...@@ -60,7 +60,7 @@ void TCPCheck::check_thread()
ost::Thread::setException(ost::Thread::throwException); ost::Thread::setException(ost::Thread::throwException);
UTCPStream t; UTCPStream t;
t.create(ip, port, true, tout_msec); t.create(ip, port, true, tout_msec);
t.setKeepAliveParams( (tout_msec > 1000 ? tout_msec/1000 : 1) ); t.setKeepAliveParams( (tout_msec > 1000 ? tout_msec / 1000 : 1) );
setResult(true); setResult(true);
t.disconnect(); t.disconnect();
} }
......
...@@ -27,8 +27,8 @@ void UTCPStream::setKeepAliveParams(timeout_t timeout_sec, int keepcnt, int keep ...@@ -27,8 +27,8 @@ void UTCPStream::setKeepAliveParams(timeout_t timeout_sec, int keepcnt, int keep
{ {
SOCKET fd = TCPStream::so; SOCKET fd = TCPStream::so;
int enable = 1; int enable = 1;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,(void*)&enable,sizeof(enable)); setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&enable, sizeof(enable));
setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void *) &keepcnt, sizeof(keepcnt)); setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void*) &keepcnt, sizeof(keepcnt));
setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void*) &keepintvl, sizeof (keepintvl)); setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void*) &keepintvl, sizeof (keepintvl));
setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void*) &timeout_sec, sizeof (timeout_sec)); setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void*) &timeout_sec, sizeof (timeout_sec));
} }
......
...@@ -13,7 +13,6 @@ LogReader::LogReader(): ...@@ -13,7 +13,6 @@ LogReader::LogReader():
inTimeout(10000), inTimeout(10000),
outTimeout(6000), outTimeout(6000),
reconDelay(5000), reconDelay(5000),
tcp(0),
iaddr(""), iaddr(""),
cmdonly(false), cmdonly(false),
readcount(0) readcount(0)
...@@ -50,9 +49,8 @@ void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t m ...@@ -50,9 +49,8 @@ void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t m
{ {
if( tcp ) if( tcp )
{ {
(*tcp) << endl; (*tcp.get()) << endl;
disconnect(); disconnect();
delete tcp;
tcp = 0; tcp = 0;
} }
...@@ -71,7 +69,7 @@ void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t m ...@@ -71,7 +69,7 @@ void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t m
try try
{ {
tcp = new UTCPStream(); tcp = make_shared<UTCPStream>();
tcp->create(iaddr, port, true, 500); tcp->create(iaddr, port, true, 500);
tcp->setTimeout(msec); tcp->setTimeout(msec);
tcp->setKeepAlive(true); tcp->setKeepAlive(true);
...@@ -85,7 +83,6 @@ void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t m ...@@ -85,7 +83,6 @@ void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t m
rlog.crit() << s.str() << std::endl; rlog.crit() << s.str() << std::endl;
} }
delete tcp;
tcp = 0; tcp = 0;
} }
catch( ... ) catch( ... )
...@@ -110,7 +107,6 @@ void LogReader::disconnect() ...@@ -110,7 +107,6 @@ void LogReader::disconnect()
rlog.info() << iaddr << "(LogReader): disconnect." << endl; rlog.info() << iaddr << "(LogReader): disconnect." << endl;
tcp->disconnect(); tcp->disconnect();
delete tcp;
tcp = 0; tcp = 0;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -200,6 +196,9 @@ void LogReader::sendCommand( const std::string& _addr, ost::tpport_t _port, std: ...@@ -200,6 +196,9 @@ void LogReader::sendCommand( const std::string& _addr, ost::tpport_t _port, std:
} }
} // end for send all command } // end for send all command
if( !isConnection() )
return;
// после команд.. выводим список текущий.. // после команд.. выводим список текущий..
timeout_t reply_timeout = 2000; // TIMEOUT_INF; timeout_t reply_timeout = 2000; // TIMEOUT_INF;
...@@ -299,7 +298,7 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServ ...@@ -299,7 +298,7 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServ
while( tcp->isPending(ost::Socket::pendingInput, inTimeout) ) while( tcp->isPending(ost::Socket::pendingInput, inTimeout) )
{ {
int n = tcp->peek( buf, sizeof(buf) - 1 ); ssize_t n = tcp->peek( buf, sizeof(buf) - 1 );
if( n > 0 ) if( n > 0 )
{ {
...@@ -308,6 +307,8 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServ ...@@ -308,6 +307,8 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServ
log << buf; log << buf;
} }
else if( n == 0 && readcount <=0 )
break;
if( rcount > 0 && readcount > 0 ) if( rcount > 0 && readcount > 0 )
rcount--; rcount--;
......
...@@ -29,10 +29,11 @@ LogServer::~LogServer() ...@@ -29,10 +29,11 @@ LogServer::~LogServer()
tcp->reject(); tcp->reject();
if( thr ) if( thr )
{
thr->stop(); thr->stop();
if( thr->isRunning() )
delete tcp; thr->join();
tcp = 0; }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
LogServer::LogServer( std::shared_ptr<LogAgregator> log ): LogServer::LogServer( std::shared_ptr<LogAgregator> log ):
...@@ -74,17 +75,7 @@ void LogServer::run( const std::string& addr, ost::tpport_t port, bool thread ) ...@@ -74,17 +75,7 @@ void LogServer::run( const std::string& addr, ost::tpport_t port, bool thread )
try try
{ {
ost::InetAddress iaddr(addr.c_str()); ost::InetAddress iaddr(addr.c_str());
tcp = new ost::TCPSocket(iaddr, port); tcp = make_shared<ost::TCPSocket>(iaddr, port);
#if 0
if( !nullsess )
{
ostringstream err;
err << "(LOG SERVER): Exceeded the limit on the number of sessions = " << sessMaxCount << endl;
nullsess = make_shared<NullLogSession>(err.str());
}
#endif
} }
catch( ost::Socket* socket ) catch( ost::Socket* socket )
{ {
...@@ -138,26 +129,28 @@ void LogServer::work() ...@@ -138,26 +129,28 @@ void LogServer::work()
ostringstream err; ostringstream err;
err << "(LOG SERVER): Exceeded the limit on the number of sessions = " << sessMaxCount << endl; err << "(LOG SERVER): Exceeded the limit on the number of sessions = " << sessMaxCount << endl;
nullsess = make_shared<NullLogSession>(err.str()); nullsess = make_shared<NullLogSession>(err.str());
nullsess->detach(); // start(); //nullsess->detach();
nullsess->start();
} }
else else
nullsess->setMessage(err.str()); nullsess->setMessage(err.str());
nullsess->add(*tcp); nullsess->add(*(tcp.get())); // опасно передавать "сырой указатель", теряем контроль
continue; continue;
} }
} }
if( cancelled ) break; if( cancelled ) break;
auto s = make_shared<LogSession>(*tcp, elog, sessTimeout, cmdTimeout, outTimeout); auto s = make_shared<LogSession>( *(tcp.get()), elog, sessTimeout, cmdTimeout, outTimeout);
s->setSessionLogLevel(sessLogLevel); s->setSessionLogLevel(sessLogLevel);
{ {
uniset_rwmutex_wrlock l(mutSList); uniset_rwmutex_wrlock l(mutSList);
slist.push_back(s); slist.push_back(s);
} }
s->connectFinalSession( sigc::mem_fun(this, &LogServer::sessionFinished) ); s->connectFinalSession( sigc::mem_fun(this, &LogServer::sessionFinished) );
s->detach(); //s->detach();
s->start();
} }
} }
catch( ost::Socket* socket ) catch( ost::Socket* socket )
...@@ -175,6 +168,10 @@ void LogServer::work() ...@@ -175,6 +168,10 @@ void LogServer::work()
else else
cerr << "client socket failed" << endl; cerr << "client socket failed" << endl;
} }
catch( const std::exception& ex )
{
cerr << "catch exception: " << ex.what() << endl;
}
} }
{ {
...@@ -185,6 +182,12 @@ void LogServer::work() ...@@ -185,6 +182,12 @@ void LogServer::work()
if( nullsess ) if( nullsess )
nullsess->cancel(); nullsess->cancel();
} }
for( const auto& i : slist )
{
if( i->isRunning() )
i->ost::Thread::join();
}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void LogServer::sessionFinished( std::shared_ptr<LogSession> s ) void LogServer::sessionFinished( std::shared_ptr<LogSession> s )
......
...@@ -18,9 +18,9 @@ using namespace UniSetTypes; ...@@ -18,9 +18,9 @@ using namespace UniSetTypes;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
LogSession::~LogSession() LogSession::~LogSession()
{ {
cancelled = true;
if( isRunning() ) if( isRunning() )
{ {
cancelled = true;
ost::Thread::join(); ost::Thread::join();
disconnect(); disconnect();
} }
...@@ -73,6 +73,10 @@ void LogSession::run() ...@@ -73,6 +73,10 @@ void LogSession::run()
if( cancelled ) if( cancelled )
return; return;
// удерживаем указатель на себя, пока работает поток..
myptr = shared_from_this();
cancelled = false;
{ {
ost::tpport_t p; ost::tpport_t p;
ost::InetAddress iaddr = getIPV4Peer(&p); ost::InetAddress iaddr = getIPV4Peer(&p);
...@@ -95,7 +99,7 @@ void LogSession::run() ...@@ -95,7 +99,7 @@ void LogSession::run()
setKeepAlive(true); setKeepAlive(true);
// Команды могут посылаться только в начале сессии.. // Команды могут посылаться только в начале сессии..
while( isPending(Socket::pendingInput, cmdTimeout) ) while( !cancelled && isPending(Socket::pendingInput, cmdTimeout) )
{ {
LogServerTypes::lsMessage msg; LogServerTypes::lsMessage msg;
...@@ -242,8 +246,6 @@ void LogSession::run() ...@@ -242,8 +246,6 @@ void LogSession::run()
#endif #endif
cancelled = false;
while( !cancelled && isConnected() ) // !ptSessionTimeout.checkTime() while( !cancelled && isConnected() ) // !ptSessionTimeout.checkTime()
{ {
// проверка только ради проверки "целостности" соединения // проверка только ради проверки "целостности" соединения
...@@ -307,18 +309,22 @@ void LogSession::run() ...@@ -307,18 +309,22 @@ void LogSession::run()
disconnect(); disconnect();
cancelled = true;
if( slog.debugging(Debug::INFO) ) if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): thread stopping..." << endl; slog[Debug::INFO] << peername << "(run): thread stopping..." << endl;
myptr = 0;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void LogSession::final() void LogSession::final()
{ {
tcp()->sync(); tcp()->sync();
cancelled = true;
try try
{ {
auto s = shared_from_this(); auto s = shared_from_this();
if( s ) if( s )
slFin(s); slFin(s);
} }
...@@ -344,8 +350,8 @@ NullLogSession::~NullLogSession() ...@@ -344,8 +350,8 @@ NullLogSession::~NullLogSession()
{ {
cancelled = true; cancelled = true;
if( isRunning() ) // if( isRunning() )
exit(); // terminate(); // exit(); // terminate();
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
void NullLogSession::add( ost::TCPSocket& sock ) void NullLogSession::add( ost::TCPSocket& sock )
......
...@@ -126,8 +126,19 @@ UniSetTypes::IDList::IDList( std::vector<std::string>&& svec ): ...@@ -126,8 +126,19 @@ UniSetTypes::IDList::IDList( std::vector<std::string>&& svec ):
UniSetTypes::IDList::IDList( std::vector<std::string>& svec ): UniSetTypes::IDList::IDList( std::vector<std::string>& svec ):
UniSetTypes::IDList::IDList() UniSetTypes::IDList::IDList()
{ {
auto conf = uniset_conf();
for( const auto& s : svec ) for( const auto& s : svec )
add( uni_atoi(s) ); {
ObjectId id;
if( is_digit(s) )
id = uni_atoi(s);
else
id = conf->getSensorID(s);
add(id);
}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
UniSetTypes::IDList::IDList(): UniSetTypes::IDList::IDList():
...@@ -488,7 +499,7 @@ int UniSetTypes::uni_atoi( const char* str ) ...@@ -488,7 +499,7 @@ int UniSetTypes::uni_atoi( const char* str )
// чтобы корректно обрабатывать большие числа типа std::numeric_limits<unsigned int>::max() // чтобы корректно обрабатывать большие числа типа std::numeric_limits<unsigned int>::max()
// \warning есть сомнения, что на 64bit-тах это будет корректно работать.. // \warning есть сомнения, что на 64bit-тах это будет корректно работать..
int n = 0; unsigned int n = 0;
if( strlen(str) > 2 ) if( strlen(str) > 2 )
{ {
...@@ -500,7 +511,7 @@ int UniSetTypes::uni_atoi( const char* str ) ...@@ -500,7 +511,7 @@ int UniSetTypes::uni_atoi( const char* str )
} }
n = std::atoll(str); // универсальнее получать unsigned..чтобы не потерять "большие числа".. n = std::atoll(str); // универсальнее получать unsigned..чтобы не потерять "большие числа"..
return n; return n; // а возвращаем int..
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
char* UniSetTypes::uni_strdup( const string& src ) char* UniSetTypes::uni_strdup( const string& src )
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
PassiveTimer::PassiveTimer( ): PassiveTimer::PassiveTimer( ):
PassiveTimer(WaitUpTime) PassiveTimer(WaitUpTime)
{ {
reset();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -72,7 +72,7 @@ void PassiveTimer::reset(void) ...@@ -72,7 +72,7 @@ void PassiveTimer::reset(void)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// получить текущее значение таймера // получить текущее значение таймера
timeout_t PassiveTimer::getCurrent() timeout_t PassiveTimer::getCurrent() const
{ {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t_start).count(); return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t_start).count();
} }
......
...@@ -105,7 +105,7 @@ namespace UniSetTypes ...@@ -105,7 +105,7 @@ namespace UniSetTypes
localNode(UniSetTypes::DefaultObjectId), localNode(UniSetTypes::DefaultObjectId),
localNodeName(""), localNodeName(""),
fileConfName(""), fileConfName(""),
heartbeat_msec(10000) heartbeat_msec(3000)
{ {
// ulog.crit()<< " configuration FAILED!!!!!!!!!!!!!!!!!" << endl; // ulog.crit()<< " configuration FAILED!!!!!!!!!!!!!!!!!" << endl;
// throw Exception(); // throw Exception();
...@@ -622,7 +622,7 @@ namespace UniSetTypes ...@@ -622,7 +622,7 @@ namespace UniSetTypes
heartbeat_msec = hit.getIntProp("msec"); heartbeat_msec = hit.getIntProp("msec");
if( heartbeat_msec <= 0 ) if( heartbeat_msec <= 0 )
heartbeat_msec = 5000; heartbeat_msec = 3000;
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -10,6 +10,10 @@ TEST_CASE("Pulse", "[Test for class 'Pulse' - impulse generator]" ) ...@@ -10,6 +10,10 @@ TEST_CASE("Pulse", "[Test for class 'Pulse' - impulse generator]" )
{ {
// Работа без задержки..(нулевые задержки) // Работа без задержки..(нулевые задержки)
Pulse p; Pulse p;
REQUIRE( p.getT1() == 0 );
REQUIRE( p.getT0() == 0 );
CHECK_FALSE( p.out() ); CHECK_FALSE( p.out() );
p.step(); p.step();
...@@ -51,5 +55,18 @@ TEST_CASE("Pulse", "[Test for class 'Pulse' - impulse generator]" ) ...@@ -51,5 +55,18 @@ TEST_CASE("Pulse", "[Test for class 'Pulse' - impulse generator]" )
CHECK( p.step() ); CHECK( p.step() );
msleep(110); msleep(110);
CHECK_FALSE( p.step() ); CHECK_FALSE( p.step() );
// проверка того, что при познем вызове step
// тоже всё будет хорошо..
p.reset();
CHECK( p.step() );
msleep(110);
CHECK_FALSE( p.step() );
msleep(2050);
CHECK( p.step() );
msleep(110);
CHECK_FALSE( p.step() );
msleep(70);
CHECK( p.step() );
} }
} }
...@@ -41,7 +41,7 @@ extensions/include/MBExchange.h ...@@ -41,7 +41,7 @@ extensions/include/MBExchange.h
extensions/include/MBSlave.h extensions/include/MBSlave.h
extensions/include/MBTCPMaster.h extensions/include/MBTCPMaster.h
extensions/include/MBTCPMultiMaster.h extensions/include/MBTCPMultiMaster.h
extensions/include/MBTCPMultiSlave.h extensions/include/MBTCPPersistentSlave.h
extensions/include/MTR.h extensions/include/MTR.h
extensions/include/PassiveLProcessor.h extensions/include/PassiveLProcessor.h
extensions/include/PID.h extensions/include/PID.h
...@@ -144,9 +144,9 @@ extensions/ModbusSlave/Makefile.am ...@@ -144,9 +144,9 @@ extensions/ModbusSlave/Makefile.am
extensions/ModbusSlave/MBSlave.cc extensions/ModbusSlave/MBSlave.cc
extensions/ModbusSlave/mbslave.cc extensions/ModbusSlave/mbslave.cc
extensions/ModbusSlave/MBSlave.h extensions/ModbusSlave/MBSlave.h
extensions/ModbusSlave/mbtcp-multislave.cc extensions/ModbusSlave/mbtcp-persistentslave.cc
extensions/ModbusSlave/MBTCPMultiSlave.cc extensions/ModbusSlave/MBTCPPersistentSlave.cc
extensions/ModbusSlave/MBTCPMultiSlave.h extensions/ModbusSlave/MBTCPPersistentSlave.h
extensions/ModbusSlave/test.xml extensions/ModbusSlave/test.xml
extensions/RRDServer/libUniSet2RRDServer.pc.in extensions/RRDServer/libUniSet2RRDServer.pc.in
extensions/RRDServer/main.cc extensions/RRDServer/main.cc
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment