Commit 807617b0 authored by Pavel Vainerman's avatar Pavel Vainerman

Merge branch 'log-monitor'

parents f9fa80af 41cba1cc
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
############################################################################ ############################################################################
SUBDIRS = scripts Admin NullController SViewer-text \ SUBDIRS = scripts Admin NullController SViewer-text \
SMonit MBTester codegen SImitator SMonit MBTester codegen SImitator ULog
bin_PROGRAMS = @PACKAGE@-log @PACKAGE@-logserver-wrap
noinst_PROGRAMS = @PACKAGE@-test-logserver @PACKAGE@-log-stdin
@PACKAGE@_test_logserver_SOURCES = logserver.cc
@PACKAGE@_test_logserver_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_test_logserver_CPPFLAGS = $(COMCPP_CFLAGS)
@PACKAGE@_log_SOURCES = log.cc
@PACKAGE@_log_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_log_CPPFLAGS = $(COMCPP_CFLAGS)
@PACKAGE@_log_stdin_SOURCES = log-stdin.cc
@PACKAGE@_log_stdin_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_log_stdin_CPPFLAGS = $(COMCPP_CFLAGS)
@PACKAGE@_logserver_wrap_SOURCES = log-wrap.cc
@PACKAGE@_logserver_wrap_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_logserver_wrap_CPPFLAGS = $(COMCPP_CFLAGS)
// --------------------------------------------------------------------------
#include <getopt.h>
#include <iostream>
#include <string>
#include "DebugStream.h"
#include "LogServer.h"
#include "Exceptions.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// -------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h - this message\n");
printf("-v - Print all messages to stdout\n");
printf("-i addr - LogServer ip or hostname. Default: localhost.\n");
printf("-p port - LogServer port. Default: 3333.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
try
{
while( (opt = getopt_long(argc, argv, "hvi:p:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
addr = string(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
cout << "(init): listen " << addr << ":" << port << endl;
DebugStream log;
LogServer ls(log);
ls.run(addr,port,true);
char buf[10000];
while( true )
{
size_t r = read(fileno(stdin), buf, sizeof(buf)-1);
if( r > 0 )
{
buf[r] = '\0';
log << buf;
}
}
}
catch( SystemError& err )
{
cerr << "(log-stdin): " << err << endl;
return 1;
}
catch( Exception& ex )
{
cerr << "(log-stdin): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(log-stdin): catch(...)" << endl;
return 1;
}
return 0;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string>
#include "DebugStream.h"
#include "UniSetTypes.h"
#include "LogServer.h"
#include "LogServerTypes.h"
#include "Exceptions.h"
#include <sys/wait.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <cstring>
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// -------------------------------------------------------------------------
static void print_help()
{
printf("\n");
printf("Usage: uniset2-logserver-wrap listen-addr listen-port PROGRAMM ARGS..\n");
printf("\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
if( argc < 4 )
{
print_help();
return 1;
}
string addr(argv[1]);
int port = atoi(argv[2]);
int pid;
int cp[2]; /* Child to parent pipe */
if( pipe(cp) < 0)
{
perror("Can't make pipe");
exit(1);
}
try
{
switch( pid = fork() )
{
case -1:
{
perror("Can't fork");
exit(1);
}
case 0:
{
/* Child. */
close(cp[0]);
close( fileno(stdout) );
dup2(cp[1],fileno(stdout));
close( fileno(stderr) );
dup2(fileno(stdout),fileno(stderr));
execvpe(argv[3], argv + 3, envp);
perror("No exec");
kill(getppid(), SIGQUIT);
exit(1);
}
break;
default:
{
/* Parent. */
close(cp[1]);
DebugStream zlog;
zlog.addLevel(Debug::ANY);
LogServer ls(zlog);
cout << "wrap: server " << addr << ":" << port << endl;
ls.run( addr, port, true );
char buf[5000];
while( true )
{
ssize_t r = read(cp[0], &buf, sizeof(buf)-1 );
if( r > 0 )
{
buf[r] = '\0';
zlog << buf;
}
}
exit(0);
}
break;
}
}
catch( SystemError& err )
{
cerr << "(logserver-wrap): " << err << endl;
return 1;
}
catch( Exception& ex )
{
cerr << "(logserver-wrap): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(logserver-wrap): catch(...)" << endl;
return 1;
}
return 0;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string>
#include <getopt.h>
#include "Debug.h"
#include "UniSetTypes.h"
#include "Exceptions.h"
#include "LogReader.h"
#include "LogServerTypes.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "verbose", no_argument, 0, 'v' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "add", required_argument, 0, 'a' },
{ "del", required_argument, 0, 'd' },
{ "set", required_argument, 0, 's' },
{ "off", required_argument, 0, 'o' },
{ "on", required_argument, 0, 'n' },
{ "rotate", required_argument, 0, 'r' },
{ "logname", required_argument, 0, 'l' },
{ "command-only", no_argument, 0, 'b' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h, --help - this message\n");
printf("-v, --verbose - Print all messages to stdout\n");
printf("[-i|--iaddr] addr - LogServer ip or hostname.\n");
printf("[-p|--port] port - LogServer port.\n");
printf("[-l|--logname] name - Send command only for 'logname'.\n");
printf("[-b|--command-only] - Send command and break. (No read logs).\n");
printf("\n");
printf("Commands:\n");
printf("[--add | -a] info,warn,crit,... - Add log levels.\n");
printf("[--del | -d] info,warn,crit,... - Delete log levels.\n");
printf("[--set | -s] info,wanr,crit,... - Set log levels.\n");
printf("--off, -o - Off the write log file (if enabled).\n");
printf("--on, -n - On the write log file (if before disabled).\n");
printf("--rotate, -r - rotate log file.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
DebugStream dlog;
int cmd = LogServerTypes::cmdNOP;
int data = 0;
string sdata("");
int cmdonly = 0;
string logname("");
try
{
while( (opt = getopt_long(argc, argv, "hva:p:i:d:s:l:onrb",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'a':
{
cmd = LogServerTypes::cmdAddLevel;
sdata = string(optarg);
}
break;
case 'd':
{
cmd = LogServerTypes::cmdDelLevel;
sdata = string(optarg);
}
break;
case 's':
{
cmd = LogServerTypes::cmdSetLevel;
sdata = string(optarg);
}
break;
case 'o':
cmd = LogServerTypes::cmdOffLogFile;
break;
case 'n':
cmd = LogServerTypes::cmdOnLogFile;
break;
case 'r':
cmd = LogServerTypes::cmdRotate;
break;
case 'i':
addr = string(optarg);
break;
case 'l':
logname = string(optarg);
break;
case 'b':
cmdonly = 1;
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): read from " << addr << ":" << port << endl;
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
LogReader lr;
lr.setCommandOnlyMode(cmdonly);
if( !sdata.empty() )
{
data = (int)Debug::value(sdata);
if( verb )
cout << "SEND COMMAND: '" << (LogServerTypes::Command)cmd << " data='" << sdata << "'" << endl;
}
lr.readlogs( addr, port, (LogServerTypes::Command)cmd, data, logname, verb );
}
catch( SystemError& err )
{
cerr << "(log): " << err << endl;
}
catch( Exception& ex )
{
cerr << "(log): " << ex << endl;
}
catch(...)
{
cerr << "(log): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string>
#include <getopt.h>
#include "Debug.h"
#include "UniSetTypes.h"
#include "Exceptions.h"
#include "LogServer.h"
#include "LogAgregator.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ "delay", required_argument, 0, 'd' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
// printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] addr - Inet address for listen connections.\n");
printf("[-p|--port] port - Bind port.\n");
printf("[-d|--delay] msec - Delay for generate message. Default 5000.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
int tout = 2000;
timeout_t delay = 5000;
try
{
while( (opt = getopt_long(argc, argv, "hvi:p:d:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
addr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'd':
delay = uni_atoi(optarg);
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): listen " << addr << ":" << port
// << " timeout=" << tout << " msec "
<< endl;
// dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
DebugStream dlog;
dlog.setLogName("dlog");
DebugStream dlog2;
dlog2.setLogName("dlog2");
LogAgregator la;
la.add(dlog);
la.add(dlog2);
LogServer ls(la);
// LogServer ls(cout);
dlog.addLevel(Debug::ANY);
dlog2.addLevel(Debug::ANY);
ls.run( addr, port, true );
unsigned int i=0;
while( true )
{
dlog << "[" << ++i << "] Test message for log" << endl;
dlog.info() << ": dlog : INFO message" << endl;
dlog.warn() << ": dlog : WARN message" << endl;
dlog.crit() << ": dlog : CRIT message" << endl;
dlog2.info() << ": dlog2: INFO message" << endl;
dlog2.warn() << ": dlog2: WARN message" << endl;
dlog2.crit() << ": dlog2: CRIT message" << endl;
msleep(delay);
}
}
catch( SystemError& err )
{
cerr << "(logserver): " << err << endl;
}
catch( Exception& ex )
{
cerr << "(logserver): " << ex << endl;
}
catch(...)
{
cerr << "(logserver): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
#!/bin/sh
for i in `seq 1 60`; do
echo "MSG$i"
sleep 1
done
\ No newline at end of file
...@@ -319,7 +319,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::sysCommand( const SystemMessage* _s ...@@ -319,7 +319,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::sysCommand( const SystemMessage* _s
string fname( mylog.getLogFile() ); string fname( mylog.getLogFile() );
if( !fname.empty() ) if( !fname.empty() )
{ {
mylog.logFile(fname.c_str()); mylog.logFile(fname.c_str(),true);
mylog &lt;&lt; myname &lt;&lt; "(sysCommand): ***************** mylog LOG ROTATE *****************" &lt;&lt; endl; mylog &lt;&lt; myname &lt;&lt; "(sysCommand): ***************** mylog LOG ROTATE *****************" &lt;&lt; endl;
} }
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<AutoStartUpTime name="1"/> <AutoStartUpTime name="1"/>
<DumpStateTime name="10"/> <DumpStateTime name="10"/>
<SleepTickMS name="500"/> <SleepTickMS name="500"/>
<UniSetDebug levels="crit,warn" name="ulog"/> <UniSetDebug levels="" name="ulog"/>
<ConfDir name="./"/> <ConfDir name="./"/>
<DataDir name="./"/> <DataDir name="./"/>
<BinDir name="./"/> <BinDir name="./"/>
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
</Services> </Services>
</UniSet> </UniSet>
<dlog name="dlog"/> <dlog name="dlog"/>
<LogServer name="smplus" port="3333" host="localhost" />
<settings> <settings>
<TestProc name="TestProc1" <TestProc name="TestProc1"
on_s="Input1_S" on_s="Input1_S"
......
...@@ -186,8 +186,8 @@ AC_SUBST(UNISET_EXT_LIBS) ...@@ -186,8 +186,8 @@ AC_SUBST(UNISET_EXT_LIBS)
# export # export
LDFLAGS="${OMNI_LIBS} ${XML_LIBS}" LDFLAGS="${OMNI_LIBS} ${XML_LIBS} ${SIGC_LIBS}"
CXXFLAGS="-pedantic -Wall -funsigned-char -std=c++11 -g -D_GNU_SOURCE ${OMNI_CFLAGS} ${XML_CFLAGS} -I\$(top_builddir)/include" CXXFLAGS="-pedantic -Wall -funsigned-char -std=c++11 -g -D_GNU_SOURCE ${OMNI_CFLAGS} ${XML_CFLAGS} ${SIGC_CFLAGS} -I\$(top_builddir)/include"
AC_SUBST(LDFLAGS) AC_SUBST(LDFLAGS)
AC_SUBST(CXXFLAGS) AC_SUBST(CXXFLAGS)
...@@ -221,12 +221,14 @@ AC_CONFIG_FILES([Makefile ...@@ -221,12 +221,14 @@ AC_CONFIG_FILES([Makefile
IDL/Processes/Makefile IDL/Processes/Makefile
src/Communications/Makefile src/Communications/Makefile
src/Communications/Modbus/Makefile src/Communications/Modbus/Makefile
src/Communications/TCP/Makefile
src/Interfaces/Makefile src/Interfaces/Makefile
src/ObjectRepository/Makefile src/ObjectRepository/Makefile
src/Processes/Makefile src/Processes/Makefile
src/Services/Makefile src/Services/Makefile
src/Timers/Makefile src/Timers/Makefile
src/Various/Makefile src/Various/Makefile
src/Log/Makefile
src/Makefile src/Makefile
include/Makefile include/Makefile
include/modbus/Makefile include/modbus/Makefile
...@@ -246,6 +248,7 @@ AC_CONFIG_FILES([Makefile ...@@ -246,6 +248,7 @@ AC_CONFIG_FILES([Makefile
Utilities/codegen/Makefile Utilities/codegen/Makefile
Utilities/codegen/uniset2-codegen Utilities/codegen/uniset2-codegen
Utilities/codegen/tests/Makefile Utilities/codegen/tests/Makefile
Utilities/ULog/Makefile
extensions/Makefile extensions/Makefile
extensions/libUniSet2Extensions.pc extensions/libUniSet2Extensions.pc
extensions/lib/Makefile extensions/lib/Makefile
......
...@@ -1226,7 +1226,7 @@ void IOControl::sysCommand( const SystemMessage* sm ) ...@@ -1226,7 +1226,7 @@ void IOControl::sysCommand( const SystemMessage* sm )
string fname( ulog.getLogFile() ); string fname( ulog.getLogFile() );
if( !fname.empty() ) if( !fname.empty() )
{ {
ulog.logFile(fname); ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << endl; ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << endl;
} }
...@@ -1234,7 +1234,7 @@ void IOControl::sysCommand( const SystemMessage* sm ) ...@@ -1234,7 +1234,7 @@ void IOControl::sysCommand( const SystemMessage* sm )
fname = dlog.getLogFile(); fname = dlog.getLogFile();
if( !fname.empty() ) if( !fname.empty() )
{ {
dlog.logFile(fname); dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** GGDEB LOG ROTATE *****************" << endl; dlog << myname << "(sysCommand): ***************** GGDEB LOG ROTATE *****************" << endl;
} }
} }
......
...@@ -148,7 +148,7 @@ void PassiveLProcessor::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -148,7 +148,7 @@ void PassiveLProcessor::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname (ulog.getLogFile() ); string fname (ulog.getLogFile() );
if( !fname.empty() ) if( !fname.empty() )
{ {
ulog.logFile(fname); ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl; ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
} }
...@@ -156,7 +156,7 @@ void PassiveLProcessor::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -156,7 +156,7 @@ void PassiveLProcessor::sysCommand( const UniSetTypes::SystemMessage *sm )
fname = dlog.getLogFile(); fname = dlog.getLogFile();
if( !fname.empty() ) if( !fname.empty() )
{ {
dlog.logFile(fname); dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl; dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
} }
} }
......
...@@ -165,13 +165,19 @@ MBExchange::~MBExchange() ...@@ -165,13 +165,19 @@ MBExchange::~MBExchange()
{ {
if( it1->second->rtu ) if( it1->second->rtu )
{ {
delete it1->second->rtu; try {
it1->second->rtu = 0; delete it1->second->rtu;
it1->second->rtu = 0;
}catch(...){}
} }
RTUDevice* d(it1->second); RTUDevice* d(it1->second);
for( auto it=d->regmap.begin(); it!=d->regmap.end(); ++it ) for( auto it=d->regmap.begin(); it!=d->regmap.end(); ++it )
delete it->second; {
try {
delete it->second;
}catch(...){}
}
delete it1->second; delete it1->second;
} }
...@@ -193,7 +199,8 @@ void MBExchange::waitSMReady() ...@@ -193,7 +199,8 @@ void MBExchange::waitSMReady()
ostringstream err; ostringstream err;
err << myname << "(waitSMReady): failed waiting SharedMemory " << ready_timeout << " msec"; err << myname << "(waitSMReady): failed waiting SharedMemory " << ready_timeout << " msec";
dcrit << err.str() << endl; dcrit << err.str() << endl;
throw SystemError(err.str()); if( checkProcActive() )
throw SystemError(err.str());
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -233,7 +240,15 @@ void MBExchange::sigterm( int signo ) ...@@ -233,7 +240,15 @@ void MBExchange::sigterm( int signo )
{ {
dwarn << myname << ": ********* SIGTERM(" << signo << ") ********" << endl; dwarn << myname << ": ********* SIGTERM(" << signo << ") ********" << endl;
setProcActive(false); setProcActive(false);
UniSetObject_LT::sigterm(signo); try
{
UniSetObject_LT::sigterm(signo);
}
catch( ... )
{
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void MBExchange::readConfiguration() void MBExchange::readConfiguration()
...@@ -1507,7 +1522,7 @@ void MBExchange::updateMTR( RegMap::iterator& rit ) ...@@ -1507,7 +1522,7 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
if( r->mtrType == MTR::mtT4 ) if( r->mtrType == MTR::mtT4 )
{ {
if( save ) if( save )
{ {
dwarn << myname << "(updateMTR): write (T4) reg(" << dat2str(r->mbreg) << ") to MTR NOT YET!!!" << endl; dwarn << myname << "(updateMTR): write (T4) reg(" << dat2str(r->mbreg) << ") to MTR NOT YET!!!" << endl;
} }
else else
...@@ -2547,14 +2562,14 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -2547,14 +2562,14 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname(ulog.getLogFile()); string fname(ulog.getLogFile());
if( !fname.empty() ) if( !fname.empty() )
{ {
ulog.logFile(fname); ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl; ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
} }
dlog << myname << "(sysCommand): logRotate" << std::endl; dlog << myname << "(sysCommand): logRotate" << std::endl;
fname = dlog.getLogFile(); fname = dlog.getLogFile();
if( !fname.empty() ) if( !fname.empty() )
{ {
dlog.logFile(fname); dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl; dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
} }
} }
...@@ -2580,7 +2595,8 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd ) ...@@ -2580,7 +2595,8 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
dcrit << err.str() << endl; dcrit << err.str() << endl;
kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс... kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс...
throw SystemError(err.str()); // throw SystemError(err.str());
return;
} }
try try
......
...@@ -75,6 +75,12 @@ pollThread(0) ...@@ -75,6 +75,12 @@ pollThread(0)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBTCPMaster::~MBTCPMaster() MBTCPMaster::~MBTCPMaster()
{ {
if( pollThread )
{
pollThread->stop();
if( pollThread->isRunning() )
pollThread->join();
}
delete pollThread; delete pollThread;
//delete mbtcp; //delete mbtcp;
} }
...@@ -146,12 +152,20 @@ void MBTCPMaster::poll_thread() ...@@ -146,12 +152,20 @@ void MBTCPMaster::poll_thread()
if( sidExchangeMode != DefaultObjectId && force ) if( sidExchangeMode != DefaultObjectId && force )
exchangeMode = shm->localGetValue(itExchangeMode,sidExchangeMode); exchangeMode = shm->localGetValue(itExchangeMode,sidExchangeMode);
} }
catch(...){} catch(...)
{
throw;
}
try try
{ {
poll(); poll();
} }
catch(...){} catch(...)
{
// if( !checkProcActive() )
throw;
}
if( !checkProcActive() ) if( !checkProcActive() )
break; break;
...@@ -160,6 +174,36 @@ void MBTCPMaster::poll_thread() ...@@ -160,6 +174,36 @@ void MBTCPMaster::poll_thread()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBTCPMaster::sigterm( int signo )
{
setProcActive(false);
if( pollThread )
{
pollThread->stop();
if( pollThread->isRunning() )
pollThread->join();
delete pollThread;
pollThread = 0;
}
try
{
MBExchange::sigterm(signo);
}
catch( const std::exception& ex )
{
cerr << "catch: " << ex.what() << endl;
}
catch( ... )
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::help_print( int argc, const char* const* argv ) void MBTCPMaster::help_print( int argc, const char* const* argv )
{ {
cout << "Default: prefix='mbtcp'" << endl; cout << "Default: prefix='mbtcp'" << endl;
......
...@@ -208,6 +208,7 @@ class MBTCPMaster: ...@@ -208,6 +208,7 @@ class MBTCPMaster:
protected: protected:
virtual void sysCommand( const UniSetTypes::SystemMessage *sm ) override; virtual void sysCommand( const UniSetTypes::SystemMessage *sm ) override;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen=false ) override; virtual std::shared_ptr<ModbusClient> initMB( bool reopen=false ) override;
virtual void sigterm( int signo ) override;
UniSetTypes::uniset_rwmutex mbMutex; UniSetTypes::uniset_rwmutex mbMutex;
std::string iaddr; std::string iaddr;
......
...@@ -78,9 +78,12 @@ int main( int argc, const char** argv ) ...@@ -78,9 +78,12 @@ int main( int argc, const char** argv )
} }
catch(...) catch(...)
{ {
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
dcrit << "(mbtcpmaster): catch ..." << std::endl; dcrit << "(mbtcpmaster): catch ..." << std::endl;
} }
on_sigchild(SIGTERM); on_sigchild(SIGTERM);
return 1; return 1;
} }
...@@ -9,106 +9,106 @@ using namespace MTR; ...@@ -9,106 +9,106 @@ using namespace MTR;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void print_help() static void print_help()
{ {
printf("Usage: mtrconv TYPE[T1...T12,T16,T17] hex1 hex2\n"); printf("Usage: mtrconv TYPE[T1...T12,T16,T17] hex1 hex2\n");
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main( int argc, const char **argv ) int main( int argc, const char **argv )
{ {
unsigned short v1 = 0; unsigned short v1 = 0;
unsigned short v2 = 0; unsigned short v2 = 0;
const char* type=""; const char* type="";
if( argc<2 ) if( argc<2 )
{ {
print_help(); print_help();
return 1; return 1;
} }
type = argv[1]; type = argv[1];
v1 = UniSetTypes::uni_atoi(argv[2]); v1 = UniSetTypes::uni_atoi(argv[2]);
if( argc>=4 ) if( argc>=4 )
{ {
v1 = UniSetTypes::uni_atoi(argv[3]); v1 = UniSetTypes::uni_atoi(argv[3]);
v2 = UniSetTypes::uni_atoi(argv[2]); v2 = UniSetTypes::uni_atoi(argv[2]);
} }
if( !strcmp(type,"T1") ) if( !strcmp(type,"T1") )
cout << "(T1): v1=" << v1 << " --> (unsigned) " << v1 << endl; cout << "(T1): v1=" << v1 << " --> (unsigned) " << v1 << endl;
else if( !strcmp(type,"T2") ) else if( !strcmp(type,"T2") )
cout << "(T2): v1=" << v1 << " --> (signed) " << (signed short)v1 << endl; cout << "(T2): v1=" << v1 << " --> (signed) " << (signed short)v1 << endl;
else if( !strcmp(type,"T16") ) else if( !strcmp(type,"T16") )
{ {
T16 t(v1); T16 t(v1);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl; cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
} }
else if( !strcmp(type,"T17") ) else if( !strcmp(type,"T17") )
{ {
T17 t(v1); T17 t(v1);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl; cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
} }
else if( !strcmp(type,"T3") ) else if( !strcmp(type,"T3") )
{ {
T3 t(v1,v2); T3 t(v1,v2);
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl; << " --> " << t << endl;
} }
else if( !strcmp(type,"T4") ) else if( !strcmp(type,"T4") )
{ {
T4 t(v1); T4 t(v1);
cout << "(T4): v1=" << t.raw cout << "(T4): v1=" << t.raw
<< " --> " << t << endl; << " --> " << t << endl;
} }
else if( !strcmp(type,"T5") ) else if( !strcmp(type,"T5") )
{ {
T5 t(v1,v2); T5 t(v1,v2);
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl; << " --> " << t << endl;
} }
else if( !strcmp(type,"T6") ) else if( !strcmp(type,"T6") )
{ {
T6 t(v1,v2); T6 t(v1,v2);
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl; << " --> " << t << endl;
} }
else if( !strcmp(type,"T7") ) else if( !strcmp(type,"T7") )
{ {
T7 t(v1,v2); T7 t(v1,v2);
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
// << " --> " << T7.val << " * 10^-4" // << " --> " << T7.val << " * 10^-4"
<< " ===> " << t << endl; << " ===> " << t << endl;
} }
else if( !strcmp(type,"T8") ) else if( !strcmp(type,"T8") )
{ {
T8 t(v1,v2); T8 t(v1,v2);
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
} }
else if( !strcmp(type,"T9") ) else if( !strcmp(type,"T9") )
{ {
T9 t(v1,v2); T9 t(v1,v2);
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
} }
else if( !strcmp(type,"T10") ) else if( !strcmp(type,"T10") )
{ {
T10 t(v1,v2); T10 t(v1,v2);
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
} }
else if( !strcmp(type,"F1") ) else if( !strcmp(type,"F1") )
{ {
F1 f(v1,v2); F1 f(v1,v2);
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1] cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f.raw.val << endl; << " ===> " << f.raw.val << endl;
} }
else else
{ {
cout << " Unknown type: " << type << endl; cout << " Unknown type: " << type << endl;
return 1; return 1;
} }
return 0; return 0;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
...@@ -12,398 +12,398 @@ using namespace UniSetTypes; ...@@ -12,398 +12,398 @@ using namespace UniSetTypes;
using namespace std; using namespace std;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static struct option longopts[] = { static struct option longopts[] = {
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ "read03", required_argument, 0, 'r' }, { "read03", required_argument, 0, 'r' },
{ "read04", required_argument, 0, 'x' }, { "read04", required_argument, 0, 'x' },
{ "read-model", required_argument, 0, 'm' }, { "read-model", required_argument, 0, 'm' },
{ "read-serial", required_argument, 0, 'n' }, { "read-serial", required_argument, 0, 'n' },
{ "device", required_argument, 0, 'd' }, { "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' }, { "verbose", no_argument, 0, 'v' },
{ "speed", required_argument, 0, 's' }, { "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' }, { "use485F", no_argument, 0, 'y' },
{ "num-cycles", required_argument, 0, 'l' }, { "num-cycles", required_argument, 0, 'l' },
{ "timeout", required_argument, 0, 't' }, { "timeout", required_argument, 0, 't' },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void print_help() static void print_help()
{ {
printf("-h|--help - this message\n"); printf("-h|--help - this message\n");
printf("[--read03] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n"); printf("[--read03] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[--read04] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n"); printf("[--read04] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[-m|--read-model] slaveaddr - read model name from MTR\n"); printf("[-m|--read-model] slaveaddr - read model name from MTR\n");
printf("[-n|--read-serial] slaveaddr - read serial number from MTR\n"); printf("[-n|--read-serial] slaveaddr - read serial number from MTR\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n"); printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n"); printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n"); printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n"); printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
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");
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
enum Command enum Command
{ {
cmdNOP, cmdNOP,
cmdRead03, cmdRead03,
cmdRead04, cmdRead04,
cmdModel, cmdModel,
cmdSerial cmdSerial
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] ); static char* checkArg( int ind, int argc, char* argv[] );
static void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, static void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
ModbusRTU::ModbusData reg, MTR::MTRType t, Command cmd ); ModbusRTU::ModbusData reg, MTR::MTRType t, Command cmd );
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
Command cmd = cmdNOP; Command cmd = cmdNOP;
int optindex = 0; int optindex = 0;
int opt = 0; int opt = 0;
int verb = 0; int verb = 0;
string dev("/dev/ttyS0"); string dev("/dev/ttyS0");
string speed("38400"); string speed("38400");
ModbusRTU::ModbusData reg = 0; ModbusRTU::ModbusData reg = 0;
ModbusRTU::ModbusAddr slaveaddr = 0x00; ModbusRTU::ModbusAddr slaveaddr = 0x00;
int tout = 2000; int tout = 2000;
DebugStream dlog; DebugStream dlog;
// string tofile(""); // string tofile("");
int use485 = 0; int use485 = 0;
int ncycles = -1; int ncycles = -1;
MTR::MTRType mtrtype = MTR::mtUnknown; MTR::MTRType mtrtype = MTR::mtUnknown;
try try
{ {
while( (opt = getopt_long(argc, argv, "hvyq:r:d:s:t:x:m:n:",longopts,&optindex)) != -1 ) while( (opt = getopt_long(argc, argv, "hvyq:r:d:s:t:x:m:n:",longopts,&optindex)) != -1 )
{ {
switch (opt) switch (opt)
{ {
case 'h': case 'h':
print_help(); print_help();
return 0; return 0;
case 'r': case 'r':
case 'x': case 'x':
{ {
if( opt == 'r' ) if( opt == 'r' )
cmd = cmdRead03; cmd = cmdRead03;
else else
cmd = cmdRead04; cmd = cmdRead04;
slaveaddr = ModbusRTU::str2mbAddr( optarg ); slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( !checkArg(optind,argc,argv) ) if( !checkArg(optind,argc,argv) )
{ {
cerr << "no argument is given: 'reg'.." << endl; cerr << "no argument is given: 'reg'.." << endl;
return 1; return 1;
} }
reg = ModbusRTU::str2mbData(argv[optind]); reg = ModbusRTU::str2mbData(argv[optind]);
if( !checkArg(optind+1,argc,argv) ) if( !checkArg(optind+1,argc,argv) )
{ {
cerr << "no argument is given: 'mtrtype'.." << endl; cerr << "no argument is given: 'mtrtype'.." << endl;
return 1; return 1;
} }
mtrtype = MTR::str2type(argv[optind+1]); mtrtype = MTR::str2type(argv[optind+1]);
if( mtrtype == MTR::mtUnknown ) if( mtrtype == MTR::mtUnknown )
{ {
cerr << "command error: Unknown mtr type: '" << string(argv[optind+1]) << "'" << endl; cerr << "command error: Unknown mtr type: '" << string(argv[optind+1]) << "'" << endl;
return 1; return 1;
} }
} }
break; break;
case 'm': case 'm':
{ {
cmd = cmdModel; cmd = cmdModel;
slaveaddr = ModbusRTU::str2mbAddr( optarg ); slaveaddr = ModbusRTU::str2mbAddr( optarg );
} }
break; break;
case 'n': case 'n':
{ {
cmd = cmdSerial; cmd = cmdSerial;
slaveaddr = ModbusRTU::str2mbAddr( optarg ); slaveaddr = ModbusRTU::str2mbAddr( optarg );
} }
break; break;
case 'y': case 'y':
use485 = 1; use485 = 1;
break; break;
case 'd': case 'd':
dev = string(optarg); dev = string(optarg);
break; break;
case 's': case 's':
speed = string(optarg); speed = string(optarg);
break; break;
case 't': case 't':
tout = uni_atoi(optarg); tout = uni_atoi(optarg);
break; break;
case 'v': case 'v':
verb = 1; verb = 1;
break; break;
case 'l': case 'l':
ncycles = uni_atoi(optarg); ncycles = uni_atoi(optarg);
break; break;
case '?': case '?':
default: default:
printf("? argumnet\n"); printf("? argumnet\n");
return 0; return 0;
} }
} }
if( verb ) if( verb )
{ {
cout << "(init): dev=" << dev << " speed=" << speed cout << "(init): dev=" << dev << " speed=" << speed
<< " timeout=" << tout << " msec " << " timeout=" << tout << " msec "
<< endl; << endl;
} }
ModbusRTUMaster mb(dev,use485); ModbusRTUMaster mb(dev,use485);
if( verb ) if( verb )
dlog.addLevel(Debug::ANY); dlog.addLevel(Debug::ANY);
mb.setTimeout(tout); mb.setTimeout(tout);
mb.setSpeed(speed); mb.setSpeed(speed);
mb.setLog(dlog); mb.setLog(dlog);
int nc = 1; int nc = 1;
if( ncycles > 0 ) if( ncycles > 0 )
nc = ncycles; nc = ncycles;
while( nc ) while( nc )
{ {
try try
{ {
switch(cmd) switch(cmd)
{ {
case cmdRead03: case cmdRead03:
case cmdRead04: case cmdRead04:
{ {
if( verb ) if( verb )
{ {
cout << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr) cout << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< " reg=" << ModbusRTU::dat2str(reg) << "(" << (int)reg << ")" << " reg=" << ModbusRTU::dat2str(reg) << "(" << (int)reg << ")"
<< " mtrType=" << MTR::type2str(mtrtype) << " mtrType=" << MTR::type2str(mtrtype)
<< endl; << endl;
} }
readMTR( &mb, slaveaddr, reg, mtrtype, cmd ); readMTR( &mb, slaveaddr, reg, mtrtype, cmd );
} }
break; break;
case cmdModel: case cmdModel:
{ {
if( verb ) if( verb )
{ {
cout << " read model name: slaveaddr=" << ModbusRTU::addr2str(slaveaddr) cout << " read model name: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< endl; << endl;
} }
string s(MTR::getModelNumber(&mb, slaveaddr)); string s(MTR::getModelNumber(&mb, slaveaddr));
cout << (s.empty()? "Don`t read model name.":s) << endl; cout << (s.empty()? "Don`t read model name.":s) << endl;
return 0; return 0;
} }
break; break;
case cmdSerial: case cmdSerial:
{ {
if( verb ) if( verb )
{ {
cout << " read serial number: slaveaddr=" << ModbusRTU::addr2str(slaveaddr) cout << " read serial number: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< endl; << endl;
} }
string s(MTR::getSerialNumber(&mb, slaveaddr)); string s(MTR::getSerialNumber(&mb, slaveaddr));
cout << (s.empty()? "Don`t read serial number.":s) << endl; cout << (s.empty()? "Don`t read serial number.":s) << endl;
return 0; return 0;
} }
break; break;
case cmdNOP: case cmdNOP:
default: default:
cerr << "No command. Use -h for help." << endl; cerr << "No command. Use -h for help." << endl;
return 1; return 1;
} }
} }
catch( ModbusRTU::mbException& ex ) catch( ModbusRTU::mbException& ex )
{ {
if( ex.err != ModbusRTU::erTimeOut ) if( ex.err != ModbusRTU::erTimeOut )
throw; throw;
cout << "timeout..." << endl; cout << "timeout..." << endl;
} }
if( ncycles > 0 ) if( ncycles > 0 )
{ {
nc--; nc--;
if( nc <=0 ) if( nc <=0 )
break; break;
} }
msleep(500); msleep(500);
} }
} }
catch( ModbusRTU::mbException& ex ) catch( ModbusRTU::mbException& ex )
{ {
cerr << "(mtr-read): " << ex << endl; cerr << "(mtr-read): " << ex << endl;
} }
catch(SystemError& err) catch(SystemError& err)
{ {
cerr << "(mtr-read): " << err << endl; cerr << "(mtr-read): " << err << endl;
} }
catch(Exception& ex) catch(Exception& ex)
{ {
cerr << "(mtr-read): " << ex << endl; cerr << "(mtr-read): " << ex << endl;
} }
catch(...) catch(...)
{ {
cerr << "(mtr-read): catch(...)" << endl; cerr << "(mtr-read): catch(...)" << endl;
} }
return 0; return 0;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] ) char* checkArg( int i, int argc, char* argv[] )
{ {
if( i<argc && (argv[i])[0]!='-' ) if( i<argc && (argv[i])[0]!='-' )
return argv[i]; return argv[i];
return 0; return 0;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
ModbusRTU::ModbusData reg, MTR::MTRType mtrType, Command cmd ) ModbusRTU::ModbusData reg, MTR::MTRType mtrType, Command cmd )
{ {
int count = MTR::wsize(mtrType); int count = MTR::wsize(mtrType);
ModbusRTU::ModbusData dat[ModbusRTU::MAXLENPACKET/sizeof(ModbusRTU::ModbusData)]; ModbusRTU::ModbusData dat[ModbusRTU::MAXLENPACKET/sizeof(ModbusRTU::ModbusData)];
memset(dat,0,sizeof(dat)); memset(dat,0,sizeof(dat));
if( cmd == cmdRead03 ) if( cmd == cmdRead03 )
{ {
ModbusRTU::ReadOutputRetMessage ret = mb->read03(addr,reg,count); ModbusRTU::ReadOutputRetMessage ret = mb->read03(addr,reg,count);
memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count); memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count);
} }
else if( cmd == cmdRead04 ) else if( cmd == cmdRead04 )
{ {
ModbusRTU::ReadInputRetMessage ret = mb->read04(addr,reg,count); ModbusRTU::ReadInputRetMessage ret = mb->read04(addr,reg,count);
memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count); memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count);
} }
else else
{ {
cerr << "Unknown command..." << endl; cerr << "Unknown command..." << endl;
return; return;
} }
if( mtrType == MTR::mtT1 ) if( mtrType == MTR::mtT1 )
{ {
MTR::T1 t(dat[0]); MTR::T1 t(dat[0]);
cout << "(T1): v1=" << dat[0] << " --> (unsigned) " << t.val << endl; cout << "(T1): v1=" << dat[0] << " --> (unsigned) " << t.val << endl;
return; return;
} }
if( mtrType == MTR::mtT2 ) if( mtrType == MTR::mtT2 )
{ {
MTR::T2 t(dat[0]); MTR::T2 t(dat[0]);
cout << "(T2): v1=" << dat[0] << " --> (signed) " << t.val << endl; cout << "(T2): v1=" << dat[0] << " --> (signed) " << t.val << endl;
return; return;
} }
if( mtrType == MTR::mtT3 ) if( mtrType == MTR::mtT3 )
{ {
MTR::T3 t(dat,MTR::T3::wsize()); MTR::T3 t(dat,MTR::T3::wsize());
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl; << " --> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT4 ) if( mtrType == MTR::mtT4 )
{ {
MTR::T4 t(dat[0]); MTR::T4 t(dat[0]);
cout << "(T4): v1=" << t.raw cout << "(T4): v1=" << t.raw
<< " --> " << t << endl; << " --> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT5 ) if( mtrType == MTR::mtT5 )
{ {
MTR::T5 t(dat,MTR::T5::wsize()); MTR::T5 t(dat,MTR::T5::wsize());
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl; << " --> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT6 ) if( mtrType == MTR::mtT6 )
{ {
MTR::T6 t(dat,MTR::T6::wsize()); MTR::T6 t(dat,MTR::T6::wsize());
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl; << " --> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT7 ) if( mtrType == MTR::mtT7 )
{ {
MTR::T7 t(dat,MTR::T7::wsize()); MTR::T7 t(dat,MTR::T7::wsize());
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT16 ) if( mtrType == MTR::mtT16 )
{ {
MTR::T16 t(dat[0]); MTR::T16 t(dat[0]);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl; cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
return; return;
} }
if( mtrType == MTR::mtT17 ) if( mtrType == MTR::mtT17 )
{ {
MTR::T17 t(dat[0]); MTR::T17 t(dat[0]);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl; cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
return; return;
} }
if( mtrType == MTR::mtF1 ) if( mtrType == MTR::mtF1 )
{ {
MTR::F1 f(dat,MTR::F1::wsize()); MTR::F1 f(dat,MTR::F1::wsize());
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1] cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f << endl; << " ===> " << f << endl;
return; return;
} }
if( mtrType == MTR::mtT8 ) if( mtrType == MTR::mtT8 )
{ {
MTR::T8 t(dat,MTR::T8::wsize()); MTR::T8 t(dat,MTR::T8::wsize());
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT9 ) if( mtrType == MTR::mtT9 )
{ {
MTR::T9 t(dat,MTR::T9::wsize()); MTR::T9 t(dat,MTR::T9::wsize());
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
return; return;
} }
if( mtrType == MTR::mtT10 ) if( mtrType == MTR::mtT10 )
{ {
MTR::T10 t(dat,MTR::T10::wsize()); MTR::T10 t(dat,MTR::T10::wsize());
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1] cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl; << " ===> " << t << endl;
return; return;
} }
cerr << "Unsupported mtrtype='" << MTR::type2str(mtrType) << "'" << endl; cerr << "Unsupported mtrtype='" << MTR::type2str(mtrType) << "'" << endl;
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
--confile test.xml \ --confile test.xml \
--mbtcp-name MBMaster1 \ --mbtcp-name MBMaster1 \
--smemory-id SharedMemory \ --smemory-id SharedMemory \
--dlog-add-levels info,crit,warn,level4,level3 \ --dlog-add-levels system,info,crit,warn,level4,level3 \
--mbtcp-set-prop-prefix \ --mbtcp-set-prop-prefix \
--mbtcp-filter-field rs \ --mbtcp-filter-field rs \
--mbtcp-filter-value 5 \ --mbtcp-filter-value 5 \
......
...@@ -9,114 +9,114 @@ using namespace VTypes; ...@@ -9,114 +9,114 @@ using namespace VTypes;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void print_help() static void print_help()
{ {
printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n"); printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n");
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main( int argc, const char **argv ) int main( int argc, const char **argv )
{ {
/* /*
VTypes::F2 f2; VTypes::F2 f2;
f2.raw.val = 2.345; f2.raw.val = 2.345;
cout << "Example(F2): float=" << f2.raw.val cout << "Example(F2): float=" << f2.raw.val
<< " regs:" << " regs:"
<< " v[0]=" << f2.raw.v[0] << " v[0]=" << f2.raw.v[0]
<< " v[1]=" << f2.raw.v[1] << " v[1]=" << f2.raw.v[1]
<< endl; << endl;
VTypes::F4 f4; VTypes::F4 f4;
f4.raw.val = 2.345123123; f4.raw.val = 2.345123123;
cout << "Example(F4): float=" << f4.raw.val cout << "Example(F4): float=" << f4.raw.val
<< " regs:" << " regs:"
<< " v[0]=" << f4.raw.v[0] << " v[0]=" << f4.raw.v[0]
<< " v[1]=" << f4.raw.v[1] << " v[1]=" << f4.raw.v[1]
<< " v[2]=" << f4.raw.v[2] << " v[2]=" << f4.raw.v[2]
<< " v[3]=" << f4.raw.v[3] << " v[3]=" << f4.raw.v[3]
<< endl; << endl;
cout << "-------------" << endl << endl; cout << "-------------" << endl << endl;
VTypes::I2 i2; VTypes::I2 i2;
i2.raw.val = -6553004; i2.raw.val = -6553004;
cout << "Example(I2): int=" << i2.raw.val cout << "Example(I2): int=" << i2.raw.val
<< " regs:" << " regs:"
<< " v[0]=" << i2.raw.v[0] << " v[0]=" << i2.raw.v[0]
<< " v[1]=" << i2.raw.v[1] << " v[1]=" << i2.raw.v[1]
<< endl; << endl;
cout << "-------------" << endl << endl; cout << "-------------" << endl << endl;
VTypes::U2 u2; VTypes::U2 u2;
u2.raw.val = 655300400; u2.raw.val = 655300400;
cout << "Example(U2): unsigned int=" << u2.raw.val cout << "Example(U2): unsigned int=" << u2.raw.val
<< " regs:" << " regs:"
<< " v[0]=" << u2.raw.v[0] << " v[0]=" << u2.raw.v[0]
<< " v[1]=" << u2.raw.v[1] << " v[1]=" << u2.raw.v[1]
<< endl; << endl;
cout << "-------------" << endl << endl; cout << "-------------" << endl << endl;
// return 0; // return 0;
*/ */
unsigned short v[4]; unsigned short v[4];
memset(v,0,sizeof(v)); memset(v,0,sizeof(v));
const char* type=""; const char* type="";
if( argc<3 ) if( argc<3 )
{ {
print_help(); print_help();
return 1; return 1;
} }
type = argv[1]; type = argv[1];
v[0] = UniSetTypes::uni_atoi(argv[2]); v[0] = UniSetTypes::uni_atoi(argv[2]);
if( argc>3 ) if( argc>3 )
v[1] = UniSetTypes::uni_atoi(argv[3]); v[1] = UniSetTypes::uni_atoi(argv[3]);
if( argc>4 ) if( argc>4 )
v[2] = UniSetTypes::uni_atoi(argv[4]); v[2] = UniSetTypes::uni_atoi(argv[4]);
if( argc>5 ) if( argc>5 )
v[3] = UniSetTypes::uni_atoi(argv[5]); v[3] = UniSetTypes::uni_atoi(argv[5]);
if( !strcmp(type,"F2") ) if( !strcmp(type,"F2") )
{ {
VTypes::F2 f(v,sizeof(v)); VTypes::F2 f(v,sizeof(v));
cout << "(F2): v[0]=" << v[0] cout << "(F2): v[0]=" << v[0]
<< " v[1]=" << v[1] << " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl; << " --> (float) " << (float)f << endl;
} }
else if( !strcmp(type,"F4") ) else if( !strcmp(type,"F4") )
{ {
VTypes::F4 f(v,sizeof(v)); VTypes::F4 f(v,sizeof(v));
cout << "(F4): v[0]=" << v[0] cout << "(F4): v[0]=" << v[0]
<< " v[1]=" << v[1] << " v[1]=" << v[1]
<< " v[2]=" << v[2] << " v[2]=" << v[2]
<< " v[3]=" << v[3] << " v[3]=" << v[3]
<< " --> (float) " << (float)f << endl; << " --> (float) " << (float)f << endl;
} }
else if( !strcmp(type,"I2") ) else if( !strcmp(type,"I2") )
{ {
VTypes::I2 i(v,sizeof(v)); VTypes::I2 i(v,sizeof(v));
cout << "(I2): v[0]=" << v[0] cout << "(I2): v[0]=" << v[0]
<< " v[1]=" << v[1] << " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl; << " --> (int) " << (int)i << endl;
} }
else if( !strcmp(type,"U2") ) else if( !strcmp(type,"U2") )
{ {
VTypes::U2 i(v,sizeof(v)); VTypes::U2 i(v,sizeof(v));
cout << "(U2): v[0]=" << v[0] cout << "(U2): v[0]=" << v[0]
<< " v[1]=" << v[1] << " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl; << " --> (unsigned int) " << (unsigned int)i << endl;
} }
else else
{ {
cout << " Unknown type: " << type << endl; cout << " Unknown type: " << type << endl;
} }
return 0; return 0;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
...@@ -623,7 +623,7 @@ void MBSlave::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -623,7 +623,7 @@ void MBSlave::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname(ulog.getLogFile()); string fname(ulog.getLogFile());
if( !fname.empty() ) if( !fname.empty() )
{ {
ulog.logFile(fname); ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl; ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
} }
...@@ -631,7 +631,7 @@ void MBSlave::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -631,7 +631,7 @@ void MBSlave::sysCommand( const UniSetTypes::SystemMessage *sm )
fname = dlog.getLogFile(); fname = dlog.getLogFile();
if( !fname.empty() ) if( !fname.empty() )
{ {
dlog.logFile(fname); dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl; dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
} }
} }
......
...@@ -264,7 +264,7 @@ CORBA::Boolean SharedMemory::exist() ...@@ -264,7 +264,7 @@ CORBA::Boolean SharedMemory::exist()
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void SharedMemory::sigterm( int signo ) void SharedMemory::sigterm( int signo )
{ {
if( signo == SIGTERM ) if( signo == SIGTERM && wdt )
wdt->stop(); wdt->stop();
// raise(SIGKILL); // raise(SIGKILL);
IONotifyController_LT::sigterm(signo); IONotifyController_LT::sigterm(signo);
......
...@@ -16,15 +16,47 @@ ...@@ -16,15 +16,47 @@
#ifdef UNISET_ENABLE_IO #ifdef UNISET_ENABLE_IO
#include "IOControl.h" #include "IOControl.h"
#endif #endif
#include "LogAgregator.h"
#include "LogServer.h"
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
using namespace std; using namespace std;
using namespace UniSetTypes; using namespace UniSetTypes;
using namespace UniSetExtensions; using namespace UniSetExtensions;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
const int MaxAddNum = 10; const unsigned int MaxAddNum = 10;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void help_print( int argc, const char* argv[] ); static void help_print( int argc, const char* argv[] );
static LogServer* run_logserver( const std::string& cnamem, DebugStream& log );
static LogServer* logserver = 0;
#ifdef UNISET_ENABLE_IO
std::list< ThreadCreator<IOControl>* > lst_iothr;
#endif
// --------------------------------------------------------------------------
void activator_terminate( int signo )
{
if( logserver )
{
try
{
delete logserver;
logserver = 0;
}
catch(...){}
}
#ifdef UNISET_IO_ENABLE
for( auto& i: lst_iothr )
{
try
{
i->stop();
}
catch(...){}
}
#endif
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main( int argc, const char **argv ) int main( int argc, const char **argv )
{ {
if( argc>1 && ( strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-h")==0 ) ) if( argc>1 && ( strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-h")==0 ) )
...@@ -45,6 +77,7 @@ int main( int argc, const char **argv ) ...@@ -45,6 +77,7 @@ int main( int argc, const char **argv )
conf->initDebug(UniSetExtensions::dlog,"dlog"); conf->initDebug(UniSetExtensions::dlog,"dlog");
UniSetActivator* act = UniSetActivator::Instance(); UniSetActivator* act = UniSetActivator::Instance();
act->signal_terminate_event().connect( &activator_terminate );
// ------------ SharedMemory ---------------- // ------------ SharedMemory ----------------
SharedMemory* shm = SharedMemory::init_smemory(argc,argv); SharedMemory* shm = SharedMemory::init_smemory(argc,argv);
if( shm == NULL ) if( shm == NULL )
...@@ -54,7 +87,7 @@ int main( int argc, const char **argv ) ...@@ -54,7 +87,7 @@ int main( int argc, const char **argv )
#ifdef UNISET_ENABLE_IO #ifdef UNISET_ENABLE_IO
// ------------ IOControl ---------------- // ------------ IOControl ----------------
std::list< ThreadCreator<IOControl>* > lst_iothr; // std::list< ThreadCreator<IOControl>* > lst_iothr;
for( unsigned int i=0; i<MaxAddNum; i++ ) for( unsigned int i=0; i<MaxAddNum; i++ )
{ {
stringstream s; stringstream s;
...@@ -122,7 +155,7 @@ int main( int argc, const char **argv ) ...@@ -122,7 +155,7 @@ int main( int argc, const char **argv )
stringstream p; stringstream p;
p << "mbs"; p << "mbs";
if( i > 0 ) p << i; if( i > 0 ) p << i;
if( dlog.is_info() ) if( dlog.is_info() )
dlog.info() << "(smemory-plus): add MBSlave(" << p.str() << ")" << endl; dlog.info() << "(smemory-plus): add MBSlave(" << p.str() << ")" << endl;
...@@ -180,13 +213,24 @@ int main( int argc, const char **argv ) ...@@ -180,13 +213,24 @@ int main( int argc, const char **argv )
act->broadcast( sm.transport_msg() ); act->broadcast( sm.transport_msg() );
#ifdef UNISET_IO_ENABLE #ifdef UNISET_IO_ENABLE
for( std::list< ThreadCreator<IOControl>* >::iterator it=lst_iothr.begin(); it!=lst_iothr.end(); ++it ) for( auto& i: lst_iothr )
(*it)->start(); i->start();
#endif #endif
LogAgregator la;
la.add(ulog);
la.add(dlog);
logserver = run_logserver("smplus",la);
if( logserver == 0 )
{
cerr << "(smemory-plus): run logserver for 'smplus' FAILED" << endl;
return 1;
}
act->run(false); act->run(false);
on_sigchild(SIGTERM);
on_sigchild(SIGTERM);
return 0; return 0;
} }
catch(Exception& ex) catch(Exception& ex)
...@@ -240,3 +284,48 @@ void help_print( int argc, const char* argv[] ) ...@@ -240,3 +284,48 @@ void help_print( int argc, const char* argv[] )
cout << "--confile - Use confile. Default: configure.xml" << endl; cout << "--confile - Use confile. Default: configure.xml" << endl;
cout << "--logfile - Use logfile. Default: smemory-plus.log" << endl; cout << "--logfile - Use logfile. Default: smemory-plus.log" << endl;
} }
// -----------------------------------------------------------------------------
LogServer* run_logserver( const std::string& cname, DebugStream& log )
{
const UniXML* xml = UniSetTypes::conf->getConfXML();
xmlNode* cnode = UniSetTypes::conf->findNode(xml->getFirstNode(),"LogServer",cname);
if( cnode == 0 )
{
cerr << "(init_ulogserver): Not found xmlnode for '" << cname << "'" << endl;
return 0;
}
UniXML::iterator it(cnode);
LogServer* ls = new LogServer( log );
timeout_t sessTimeout = conf->getArgPInt("--" + cname + "-session-timeout",it.getProp("sessTimeout"),3600000);
timeout_t cmdTimeout = conf->getArgPInt("--" + cname + "-cmd-timeout",it.getProp("cmdTimeout"),2000);
timeout_t outTimeout = conf->getArgPInt("--" + cname + "-out-timeout",it.getProp("outTimeout"),2000);
ls->setSessionTimeout(sessTimeout);
ls->setCmdTimeout(cmdTimeout);
ls->setOutTimeout(outTimeout);
std::string host = conf->getArgParam("--" + cname + "-host",it.getProp("host"));
if( host.empty() )
{
cerr << "(init_ulogserver): " << cname << ": unknown host.." << endl;
delete ls;
return 0;
}
ost::tpport_t port = conf->getArgPInt("--" + cname + "-port",it.getProp("port"),0);
if( port == 0 )
{
cerr << "(init_ulogserver): " << cname << ": unknown port.." << endl;
delete ls;
return 0;
}
cout << "logserver: " << host << ":" << port << endl;
ls->run(host, port, true);
return ls;
}
// -----------------------------------------------------------------------------
...@@ -4,7 +4,6 @@ ulimit -Sc 10000000 ...@@ -4,7 +4,6 @@ ulimit -Sc 10000000
START=uniset2-start.sh START=uniset2-start.sh
${START} -f ./uniset2-smemory-plus --smemory-id SharedMemory --confile test.xml \ ${START} -f ./uniset2-smemory-plus --smemory-id SharedMemory --confile test.xml \
--dlog-add-levels any \
--io-name IOControl \ --io-name IOControl \
--io-polltime 100 \ --io-polltime 100 \
--io-s-filter-field io \ --io-s-filter-field io \
...@@ -31,6 +30,8 @@ ${START} -f ./uniset2-smemory-plus --smemory-id SharedMemory --confile test.xml ...@@ -31,6 +30,8 @@ ${START} -f ./uniset2-smemory-plus --smemory-id SharedMemory --confile test.xml
--mbtcp2-gateway-port 2049 \ --mbtcp2-gateway-port 2049 \
--mbtcp2-recv-timeout 200 \ --mbtcp2-recv-timeout 200 \
--mbtcp2-force-out 1 \ --mbtcp2-force-out 1 \
--ulog-add-levels system \
$*
# --add-rtu \ # --add-rtu \
# --rs-dev /dev/cbsideA1 \ # --rs-dev /dev/cbsideA1 \
# --rs-id RTUExchange \ # --rs-id RTUExchange \
......
...@@ -523,7 +523,7 @@ void UNetExchange::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -523,7 +523,7 @@ void UNetExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname(ulog.getLogFile()); string fname(ulog.getLogFile());
if( !fname.empty() ) if( !fname.empty() )
{ {
ulog.logFile(fname); ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl; ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
} }
...@@ -531,7 +531,7 @@ void UNetExchange::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -531,7 +531,7 @@ void UNetExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
fname = dlog.getLogFile(); fname = dlog.getLogFile();
if( !fname.empty() ) if( !fname.empty() )
{ {
dlog.logFile(fname); dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl; dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
} }
} }
......
...@@ -26,7 +26,7 @@ namespace UniSetExtensions ...@@ -26,7 +26,7 @@ namespace UniSetExtensions
Calibration* buildCalibrationDiagram( const std::string& dname ); Calibration* buildCalibrationDiagram( const std::string& dname );
void on_sigchild( int sig ); void on_sigchild( int sig );
extern DebugStream dlog; extern DebugStream dlog;
} }
......
...@@ -21,24 +21,24 @@ ...@@ -21,24 +21,24 @@
#include "DebugStream.h" #include "DebugStream.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class UObject_SK: class UObject_SK:
public UniSetObject, public UniSetObject,
public LT_Object public LT_Object
{ {
public: public:
UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::conf->getNode("UObject"), const std::string& argprefix="" ); UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::conf->getNode("UObject"), const std::string& argprefix="" );
UObject_SK(); UObject_SK();
virtual ~UObject_SK(); virtual ~UObject_SK();
bool alarm( UniSetTypes::ObjectId sid, bool state ); bool alarm( UniSetTypes::ObjectId sid, bool state );
long getValue( UniSetTypes::ObjectId sid ); long getValue( UniSetTypes::ObjectId sid );
void setValue( UniSetTypes::ObjectId sid, long value ); void setValue( UniSetTypes::ObjectId sid, long value );
void askSensor( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand, UniSetTypes::ObjectId node = UniSetTypes::conf->getLocalNode() ); void askSensor( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand, UniSetTypes::ObjectId node = UniSetTypes::conf->getLocalNode() );
void updateValues(); void updateValues();
void setMsg( UniSetTypes::ObjectId code, bool state ); void setMsg( UniSetTypes::ObjectId code, bool state );
DebugStream mylog; DebugStream mylog;
void init_dlog( DebugStream& d ); void init_dlog( DebugStream& d );
// "синтаксический сахар"..для логов // "синтаксический сахар"..для логов
#define myinfo if( mylog.debugging(Debug::INFO) ) mylog #define myinfo if( mylog.debugging(Debug::INFO) ) mylog
...@@ -55,86 +55,86 @@ class UObject_SK: ...@@ -55,86 +55,86 @@ class UObject_SK:
#define mylog9 if( mylog.debugging(Debug::LEVEL9) ) mylog #define mylog9 if( mylog.debugging(Debug::LEVEL9) ) mylog
// Используемые идентификаторы // Используемые идентификаторы
// Используемые идентификаторы сообщений // Используемые идентификаторы сообщений
// Текущее значение и предыдущее значение // Текущее значение и предыдущее значение
// --- public variables --- // --- public variables ---
// --- end of public variables --- // --- end of public variables ---
protected: protected:
// --- protected variables --- // --- protected variables ---
// ---- end of protected variables ---- // ---- end of protected variables ----
virtual void callback(); virtual void callback();
virtual void processingMessage( UniSetTypes::VoidMessage* msg ); virtual void processingMessage( UniSetTypes::VoidMessage* msg );
virtual void sysCommand( const UniSetTypes::SystemMessage* sm ); virtual void sysCommand( const UniSetTypes::SystemMessage* sm );
virtual void askSensors( UniversalIO::UIOCommand cmd ){} virtual void askSensors( UniversalIO::UIOCommand cmd ){}
virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ){} virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ){}
virtual void timerInfo( const UniSetTypes::TimerMessage* tm ){} virtual void timerInfo( const UniSetTypes::TimerMessage* tm ){}
virtual void sigterm( int signo ); virtual void sigterm( int signo );
virtual bool activateObject(); virtual bool activateObject();
virtual void testMode( bool state ); virtual void testMode( bool state );
void updatePreviousValues(); void updatePreviousValues();
void checkSensors(); void checkSensors();
void updateOutputs( bool force ); void updateOutputs( bool force );
void preAskSensors( UniversalIO::UIOCommand cmd ); void preAskSensors( UniversalIO::UIOCommand cmd );
void preSensorInfo( const UniSetTypes::SensorMessage* sm ); void preSensorInfo( const UniSetTypes::SensorMessage* sm );
void preTimerInfo( const UniSetTypes::TimerMessage* tm ); void preTimerInfo( const UniSetTypes::TimerMessage* tm );
void waitSM( int wait_msec, UniSetTypes::ObjectId testID = UniSetTypes::DefaultObjectId ); void waitSM( int wait_msec, UniSetTypes::ObjectId testID = UniSetTypes::DefaultObjectId );
void resetMsg(); void resetMsg();
Trigger trResetMsg; Trigger trResetMsg;
PassiveTimer ptResetMsg; PassiveTimer ptResetMsg;
int resetMsgTime; int resetMsgTime;
// Выполнение очередного шага программы // Выполнение очередного шага программы
virtual void step()=0; virtual void step()=0;
int sleep_msec; /*!< пауза между итерациями */ int sleep_msec; /*!< пауза между итерациями */
bool active; bool active;
UniSetTypes::ObjectId smTestID; /*!< идентификатор датчика для тестирования готовности SM */ UniSetTypes::ObjectId smTestID; /*!< идентификатор датчика для тестирования готовности SM */
// управление датчиком "сердцебиения" // управление датчиком "сердцебиения"
PassiveTimer ptHeartBeat; /*! < период "сердцебиения" */ PassiveTimer ptHeartBeat; /*! < период "сердцебиения" */
UniSetTypes::ObjectId idHeartBeat; /*! < идентификатор датчика (AI) "сердцебиения" */ UniSetTypes::ObjectId idHeartBeat; /*! < идентификатор датчика (AI) "сердцебиения" */
int maxHeartBeat; /*! < сохраняемое значение */ int maxHeartBeat; /*! < сохраняемое значение */
xmlNode* confnode; xmlNode* confnode;
/*! получить числовое свойство из конф. файла по привязанной confnode */ /*! получить числовое свойство из конф. файла по привязанной confnode */
int getIntProp(const std::string& name) { return UniSetTypes::conf->getIntProp(confnode, name); } int getIntProp(const std::string& name) { return UniSetTypes::conf->getIntProp(confnode, name); }
/*! получить текстовое свойство из конф. файла по привязанной confnode */ /*! получить текстовое свойство из конф. файла по привязанной confnode */
inline const std::string getProp(const std::string& name) { return UniSetTypes::conf->getProp(confnode, name); } inline const std::string getProp(const std::string& name) { return UniSetTypes::conf->getProp(confnode, name); }
int smReadyTimeout; /*!< время ожидания готовности SM */ int smReadyTimeout; /*!< время ожидания готовности SM */
std::atomic_bool activated; std::atomic_bool activated;
int activateTimeout; /*!< время ожидания готовности UniSetObject к работе */ int activateTimeout; /*!< время ожидания готовности UniSetObject к работе */
PassiveTimer ptStartUpTimeout; /*!< время на блокировку обработки WatchDog, если недавно был StartUp */ PassiveTimer ptStartUpTimeout; /*!< время на блокировку обработки WatchDog, если недавно был StartUp */
int askPause; /*!< пауза между неудачными попытками заказать датчики */ int askPause; /*!< пауза между неудачными попытками заказать датчики */
IOController_i::SensorInfo si; IOController_i::SensorInfo si;
private: private:
// --- private variables --- // --- private variables ---
// --- end of private variables --- // --- end of private variables ---
bool end_private; // вспомогательное поле (для внутреннего использования при генерировании кода) bool end_private; // вспомогательное поле (для внутреннего использования при генерировании кода)
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -273,7 +273,7 @@ void UObject_SK::sysCommand( const SystemMessage* _sm ) ...@@ -273,7 +273,7 @@ void UObject_SK::sysCommand( const SystemMessage* _sm )
string fname( mylog.getLogFile() ); string fname( mylog.getLogFile() );
if( !fname.empty() ) if( !fname.empty() )
{ {
mylog.logFile(fname.c_str()); mylog.logFile(fname.c_str(),true);
mylog << myname << "(sysCommand): ***************** mylog LOG ROTATE *****************" << endl; mylog << myname << "(sysCommand): ***************** mylog LOG ROTATE *****************" << endl;
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
// but should be adaptable to any project. // but should be adaptable to any project.
// (c) 2002 adapted for UniSet by Lav, GNU GPL license // (c) 2002 adapted for UniSet by Lav, GNU GPL license
// Modify for UniSet by pv@eterspft.ru, GNU GPL license
#ifndef DEBUGSTREAM_H #ifndef DEBUGSTREAM_H
#define DEBUGSTREAM_H #define DEBUGSTREAM_H
...@@ -20,6 +21,8 @@ ...@@ -20,6 +21,8 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <sigc++/sigc++.h>
#include "Debug.h"
#ifdef TEST_DEBUGSTREAM #ifdef TEST_DEBUGSTREAM
#include <string> #include <string>
...@@ -86,10 +89,13 @@ public: ...@@ -86,10 +89,13 @@ public:
/// Constructor, sets the log file to f, and the debug level to t. /// Constructor, sets the log file to f, and the debug level to t.
explicit explicit
DebugStream(char const * f, Debug::type t = Debug::NONE); DebugStream(char const * f, Debug::type t = Debug::NONE, bool truncate=false );
/// ///
~DebugStream(); virtual ~DebugStream();
typedef sigc::signal<void,const std::string&> StreamEvent_Signal;
StreamEvent_Signal signal_stream_event();
/// Sets the debug level to t. /// Sets the debug level to t.
void level(Debug::type t) { void level(Debug::type t) {
...@@ -112,7 +118,7 @@ public: ...@@ -112,7 +118,7 @@ public:
} }
/// Sets the debugstreams' logfile to f. /// Sets the debugstreams' logfile to f.
void logFile( const std::string& f ); virtual void logFile( const std::string& f, bool truncate=false );
inline std::string getLogFile(){ return fname; } inline std::string getLogFile(){ return fname; }
...@@ -194,7 +200,13 @@ public: ...@@ -194,7 +200,13 @@ public:
const DebugStream &operator=(const DebugStream& r); const DebugStream &operator=(const DebugStream& r);
private: inline void setLogName( const std::string& n ){ logname = n; }
inline std::string getLogName(){ return logname; }
protected:
void sbuf_overflow( const std::string& s );
// private:
/// The current debug level /// The current debug level
Debug::type dt; Debug::type dt;
/// The no-op stream. /// The no-op stream.
...@@ -206,6 +218,8 @@ private: ...@@ -206,6 +218,8 @@ private:
bool show_datetime; bool show_datetime;
std::string fname; std::string fname;
StreamEvent_Signal s_stream;
std::string logname;
}; };
#endif #endif
#ifndef LogAgregator_H_
#define LogAgregator_H_
// -------------------------------------------------------------------------
#include <string>
#include <list>
#include "DebugStream.h"
#include "LogServerTypes.h"
// -------------------------------------------------------------------------
class LogAgregator:
public DebugStream
{
public:
explicit LogAgregator( Debug::type t = Debug::NONE );
explicit LogAgregator( char const * f, Debug::type t = Debug::NONE );
virtual ~LogAgregator();
virtual void logFile( const std::string& f );
void add( DebugStream& log );
// Управление "подчинёнными" логами
void addLevel( const std::string& logname, Debug::type t );
void delLevel( const std::string& logname, Debug::type t );
void level( const std::string& logname, Debug::type t );
struct LogInfo
{
LogInfo():log(0),logfile(""){}
LogInfo( DebugStream* l ):log(l),logfile(l->getLogFile()){}
DebugStream* log;
std::string logfile;
};
DebugStream* getLog( const std::string& logname );
LogInfo getLogInfo( const std::string& logname );
protected:
void logOnEvent( const std::string& s );
private:
typedef std::list<LogInfo> LogList;
LogList llst;
};
// -------------------------------------------------------------------------
#endif // LogAgregator_H_
// -------------------------------------------------------------------------
#ifndef LogReader_H_
#define LogReader_H_
// -------------------------------------------------------------------------
#include <string>
#include <queue>
#include <cc++/socket.h>
#include "UTCPStream.h"
#include "DebugStream.h"
#include "LogServerTypes.h"
// -------------------------------------------------------------------------
class LogReader
{
public:
LogReader();
~LogReader();
void readlogs( const std::string& addr, ost::tpport_t port,
LogServerTypes::Command c = LogServerTypes::cmdNOP,
int data = 0,
const std::string& logname="",
bool verbose = false );
void readlogs( const std::string& addr, ost::tpport_t port, LogServerTypes::lsMessage& m, bool verbose = false );
bool isConnection();
inline void setCommandOnlyMode( bool s ){ cmdonly = s; }
protected:
void connect( const std::string& addr, ost::tpport_t port, timeout_t tout=TIMEOUT_INF );
void connect( ost::InetAddress addr, ost::tpport_t port, timeout_t tout=TIMEOUT_INF );
void disconnect();
private:
UTCPStream* tcp;
std::string iaddr;
ost::tpport_t port;
bool cmdonly;
DebugStream rlog;
};
// -------------------------------------------------------------------------
#endif // LogReader_H_
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#ifndef LogServer_H_
#define LogServer_H_
// -------------------------------------------------------------------------
#include <list>
#include <string>
#include <cc++/socket.h>
#include "Mutex.h"
#include "DebugStream.h"
#include "ThreadCreator.h"
class LogSession;
// -------------------------------------------------------------------------
/*! \page pgLogServer Лог сервер
Лог сервер предназначен для возможности удалённого чтения логов (DebugStream).
Ему указывается host и port для прослушивания запросов, которые можно делать при помощи
LogReader. Читающих клиентов может быть скольугодно много, на каждого создаётся своя "сессия"(LogSession).
При этом через лог сервер имеется возможность управлять включением или отключением определённых уровней логов,
записью, отключением записи или ротацией файла с логами. DebugStream за которым ведётся "слежение"
задаётся в конструкторе для LogServer.
\code
DebugStream mylog;
LogServer logsrv(mylog);
...
logsrv.run(host,port,create_thread);
...
\endcode
При этом если необходимо управлять или читать сразу несколько логов можно воспользоваться специальным классом LogAgregator.
\code
DebugStream log1;
log1.setLogName("log1");
DebugStream log2;
log2.setLogName("log2");
LogAgregator la;
la.add(log1);
la.add(log2);
LogServer logsrv(la);
...
logsrv.run(host,port,create_thread);
...
\endcode
*/
// -------------------------------------------------------------------------
class LogServer
{
public:
LogServer( DebugStream& log );
LogServer( std::ostream& os );
~LogServer();
inline void setSessionTimeout( timeout_t msec ){ sessTimeout = msec; }
inline void setCmdTimeout( timeout_t msec ){ cmdTimeout = msec; }
inline void setOutTimeout( timeout_t msec ){ outTimeout = msec; }
void run( const std::string& addr, ost::tpport_t port, bool thread=true );
protected:
LogServer();
void work();
void sessionFinished( LogSession* s );
private:
typedef std::list<LogSession*> SessionList;
SessionList slist;
UniSetTypes::uniset_rwmutex mutSList;
timeout_t timeout;
timeout_t sessTimeout;
timeout_t cmdTimeout;
timeout_t outTimeout;
std::atomic_bool cancelled;
DebugStream mylog;
ThreadCreator<LogServer>* thr;
ost::TCPSocket* tcp;
DebugStream* elog;
std::ostream* oslog;
};
// -------------------------------------------------------------------------
#endif // LogServer_H_
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#ifndef LogServerTypes_H_
#define LogServerTypes_H_
// -------------------------------------------------------------------------
#include <ostream>
#include <cstring>
// -------------------------------------------------------------------------
namespace LogServerTypes
{
const unsigned int MAGICNUM = 0x20140904;
enum Command
{
cmdNOP, /*!< отсутствие команды */
cmdSetLevel, /*!< установить уровень вывода */
cmdAddLevel, /*!< добавить уровень вывода */
cmdDelLevel, /*!< удалить уровень вывода */
cmdRotate, /*!< пересоздать файл с логами */
cmdOffLogFile, /*!< отключить запись файла логов (если включена) */
cmdOnLogFile /*!< включить запись файла логов (если была отключена) */
// cmdSetLogFile
};
std::ostream& operator<<(std::ostream& os, Command c );
struct lsMessage
{
lsMessage():magic(MAGICNUM),cmd(cmdNOP),data(0){ std::memset(logname,0,sizeof(logname)); }
unsigned int magic;
Command cmd;
unsigned int data;
static const size_t MAXLOGNAME = 20;
char logname[MAXLOGNAME+1]; // +1 reserverd for '\0'
void setLogName( const std::string& name );
// для команды 'cmdSetLogFile'
// static const size_t MAXLOGFILENAME = 200;
// char logfile[MAXLOGFILENAME];
}__attribute__((packed));
std::ostream& operator<<(std::ostream& os, lsMessage& m );
}
// -------------------------------------------------------------------------
#endif // LogServerTypes_H_
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#ifndef LogSession_H_
#define LogSession_H_
// -------------------------------------------------------------------------
#include <string>
#include <deque>
#include <cc++/socket.h>
#include "Mutex.h"
#include "DebugStream.h"
#include "PassiveTimer.h"
// -------------------------------------------------------------------------
/*! Реализация "сессии" для клиентов LogServer. */
class LogSession:
public ost::TCPSession
{
public:
LogSession( ost::TCPSocket &server, DebugStream* log, timeout_t sessTimeout=10000, timeout_t cmdTimeout=2000, timeout_t outTimeout=2000, timeout_t delay=2000 );
virtual ~LogSession();
typedef sigc::slot<void, LogSession*> FinalSlot;
void connectFinalSession( FinalSlot sl );
inline std::string getClientAddress(){ return caddr; }
protected:
virtual void run();
virtual void final();
void logOnEvent( const std::string& s );
void readStream();
private:
typedef std::deque<std::string> LogBuffer;
LogBuffer lbuf;
std::string peername;
std::string caddr;
DebugStream* log;
timeout_t sessTimeout;
timeout_t cmdTimeout;
timeout_t outTimeout;
timeout_t delayTime;
PassiveTimer ptSessionTimeout;
FinalSlot slFin;
std::atomic_bool cancelled;
UniSetTypes::uniset_rwmutex mLBuf;
DebugStream slog;
};
// -------------------------------------------------------------------------
#endif // LogSession_H_
// -------------------------------------------------------------------------
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
#include "IONotifyController.h" #include "IONotifyController.h"
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
/*! /*!
Интерфейс для записи в файл и восстановления из файла списка заказчиков по датчикам для Интерфейс для записи в файл и восстановления из файла списка заказчиков по датчикам для
IONotifyController-а (NC). IONotifyController-а (NC).
\note Это абстрактный интерфейс. В чистом виде не используется. \note Это абстрактный интерфейс. В чистом виде не используется.
*/ */
...@@ -108,8 +108,8 @@ class NCRestorer ...@@ -108,8 +108,8 @@ class NCRestorer
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
/*! /*!
* \brief Реализация сохранения списка заказчиков в xml. * \brief Реализация сохранения списка заказчиков в xml.
Данный класс работает с глобальным xml-файлом проекта (обычно configure.xml), Данный класс работает с глобальным xml-файлом проекта (обычно configure.xml),
поэтому НЕ реализаует функции записи (dump)-а. поэтому НЕ реализаует функции записи (dump)-а.
*/ */
class NCRestorer_XML: class NCRestorer_XML:
public Restorer_XML, public Restorer_XML,
......
...@@ -177,9 +177,8 @@ template <class ThreadMaster> ...@@ -177,9 +177,8 @@ template <class ThreadMaster>
void ThreadCreator<ThreadMaster>::run() void ThreadCreator<ThreadMaster>::run()
{ {
pid = getpid(); pid = getpid();
if(m) if( m )
(m->*act)(); (m->*act)();
// PosixThread::stop()
} }
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
template <class ThreadMaster> template <class ThreadMaster>
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
#include <deque> #include <deque>
#include <omniORB4/CORBA.h> #include <omniORB4/CORBA.h>
#include <cc++/socket.h>
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "UniSetObject.h" #include "UniSetObject.h"
#include "UniSetManager.h" #include "UniSetManager.h"
...@@ -67,6 +68,9 @@ class UniSetActivator: ...@@ -67,6 +68,9 @@ class UniSetActivator:
virtual UniSetTypes::ObjectType getType() override { return UniSetTypes::ObjectType("UniSetActivator"); } virtual UniSetTypes::ObjectType getType() override { return UniSetTypes::ObjectType("UniSetActivator"); }
typedef sigc::signal<void,int> TerminateEvent_Signal;
TerminateEvent_Signal signal_terminate_event();
protected: protected:
/*! Команды доступные при заказе сигналов /*! Команды доступные при заказе сигналов
...@@ -118,6 +122,7 @@ class UniSetActivator: ...@@ -118,6 +122,7 @@ class UniSetActivator:
ThreadCreator<UniSetActivator> *orbthr; ThreadCreator<UniSetActivator> *orbthr;
CORBA::ORB_var orb; CORBA::ORB_var orb;
TerminateEvent_Signal s_term;
bool omDestroy; bool omDestroy;
bool sig; bool sig;
......
...@@ -77,7 +77,7 @@ class UniSetManager: ...@@ -77,7 +77,7 @@ class UniSetManager:
virtual bool addManager( UniSetManager *mngr ); virtual bool addManager( UniSetManager *mngr );
virtual bool removeManager( UniSetManager *mngr ); virtual bool removeManager( UniSetManager *mngr );
/*! Получение доступа к подчиненному менеджеру по идентификатору /*! Получение доступа к подчиненному менеджеру по идентификатору
* \return объект ненайден будет возвращен 0. * \return объект ненайден будет возвращен 0.
*/ */
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
class WDTInterface class WDTInterface
{ {
public: public:
WDTInterface(const std::string& dev); WDTInterface( const std::string& dev );
~WDTInterface(); ~WDTInterface();
bool ping(); bool ping();
......
...@@ -15,10 +15,11 @@ libUniSet2_la_LDFLAGS = -version-info @LIBVER@ ...@@ -15,10 +15,11 @@ libUniSet2_la_LDFLAGS = -version-info @LIBVER@
libUniSet2_la_LIBADD = -lm \ libUniSet2_la_LIBADD = -lm \
$(top_builddir)/src/Communications/libCommunications.la \ $(top_builddir)/src/Communications/libCommunications.la \
$(top_builddir)/src/Communications/Modbus/libModbus.la \ $(top_builddir)/src/Communications/Modbus/libModbus.la \
$(top_builddir)/src/Communications/TCP/libTCP.la \
$(top_builddir)/src/Interfaces/libInterfaces.la \ $(top_builddir)/src/Interfaces/libInterfaces.la \
$(top_builddir)/src/ObjectRepository/libObjectsRepository.la \ $(top_builddir)/src/ObjectRepository/libObjectsRepository.la \
$(top_builddir)/src/Processes/libProcesses.la \ $(top_builddir)/src/Processes/libProcesses.la \
$(top_builddir)/src/Services/libServices.la \ $(top_builddir)/src/Services/libServices.la \
$(top_builddir)/src/Timers/libTimers.la \ $(top_builddir)/src/Timers/libTimers.la \
$(top_builddir)/src/Various/libVarious.la $(top_builddir)/src/Various/libVarious.la \
$(top_builddir)/src/Log/libLog.la
############################################################################ ############################################################################
# This file is part of the UniSet library # # This file is part of the UniSet library #
############################################################################ ############################################################################
SUBDIRS=Modbus SUBDIRS=TCP Modbus
noinst_LTLIBRARIES = libCommunications.la noinst_LTLIBRARIES = libCommunications.la
libCommunications_la_SOURCES = ComPort.cc ComPort485F.cc libCommunications_la_SOURCES = ComPort.cc ComPort485F.cc
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
# This file is part of the UniSet library # # This file is part of the UniSet library #
############################################################################ ############################################################################
noinst_LTLIBRARIES = libModbus.la noinst_LTLIBRARIES = libModbus.la
libModbus_la_SOURCES = ModbusTypes.cc ModbusHelpers.cc ModbusTCPSession.cc UTCPStream.cc \ libModbus_la_SOURCES = ModbusTypes.cc ModbusHelpers.cc ModbusTCPSession.cc \
ModbusClient.cc ModbusServer.cc ModbusServerSlot.cc \ ModbusClient.cc ModbusServer.cc ModbusServerSlot.cc \
ModbusRTUSlave.cc ModbusRTUSlaveSlot.cc ModbusRTUMaster.cc \ ModbusRTUSlave.cc ModbusRTUSlaveSlot.cc ModbusRTUMaster.cc \
ModbusTCPCore.cc ModbusTCPServer.cc ModbusTCPServerSlot.cc ModbusTCPMaster.cc TCPCheck.cc ModbusTCPCore.cc ModbusTCPServer.cc ModbusTCPServerSlot.cc ModbusTCPMaster.cc
libModbus_la_CXXFLAGS = -I$(top_builddir)/include/Communications/modbus $(SIGC_CFLAGS) $(COMCPP_CFLAGS) libModbus_la_CXXFLAGS = -I$(top_builddir)/include/Communications/modbus $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
#libModbus_la_LIBADD = $(top_builddir)/src/Communications/TCP/libTCP.la $(SIGC_LIBS) $(COMCPP_LIBS)
libModbus_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS) libModbus_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
...@@ -165,7 +165,7 @@ bool ModbusRTU::isWriteFunction( SlaveFunctionCode c ) ...@@ -165,7 +165,7 @@ bool ModbusRTU::isWriteFunction( SlaveFunctionCode c )
c == fnForceSingleCoil || c == fnForceSingleCoil ||
c == fnForceMultipleCoils ) c == fnForceMultipleCoils )
return true; return true;
return false; return false;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -177,10 +177,10 @@ std::ostream& ModbusRTU::mbPrintMessage( std::ostream& os, ModbusByte* m, int le ...@@ -177,10 +177,10 @@ std::ostream& ModbusRTU::mbPrintMessage( std::ostream& os, ModbusByte* m, int le
// << setiosflags(ios::showbase) // для вывода в формате 0xNN // << setiosflags(ios::showbase) // для вывода в формате 0xNN
s << hex << showbase << setfill('0'); // << showbase; s << hex << showbase << setfill('0'); // << showbase;
for( unsigned int i=0; i<len; i++ ) for( ssize_t i=0; i<len; i++ )
s << setw(2) << (short)(m[i]) << " "; s << setw(2) << (short)(m[i]) << " ";
// s << "<" << setw(2) << (int)(m[i]) << ">"; // s << "<" << setw(2) << (int)(m[i]) << ">";
return os << s.str(); return os << s.str();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -965,7 +965,7 @@ ModbusMessage ReadOutputRetMessage::transport_msg() ...@@ -965,7 +965,7 @@ ModbusMessage ReadOutputRetMessage::transport_msg()
// Создаём временно массив, переворачиваем байты // Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[count]; ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]); dtmp[i] = SWAPSHORT(data[i]);
// копируем // копируем
...@@ -1109,17 +1109,17 @@ void ReadInputRetMessage::init( ModbusMessage& m ) ...@@ -1109,17 +1109,17 @@ void ReadInputRetMessage::init( ModbusMessage& m )
count = cnt; count = cnt;
bcnt = m.data[0]; bcnt = m.data[0];
memcpy(&data,&(m.data[1]),bcnt); memcpy(&data,&(m.data[1]),bcnt);
// переворачиваем данные // переворачиваем данные
swapData(); swapData();
memcpy(&crc,&(m.data[bcnt+1]),szCRC); memcpy(&crc,&(m.data[bcnt+1]),szCRC);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ReadInputRetMessage::swapData() void ReadInputRetMessage::swapData()
{ {
// переворачиваем данные // переворачиваем данные
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
data[i] = SWAPSHORT(data[i]); data[i] = SWAPSHORT(data[i]);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -1174,7 +1174,7 @@ ModbusMessage ReadInputRetMessage::transport_msg() ...@@ -1174,7 +1174,7 @@ ModbusMessage ReadInputRetMessage::transport_msg()
// Создаём временно массив, переворачиваем байты // Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[count]; ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]); dtmp[i] = SWAPSHORT(data[i]);
// копируем // копируем
...@@ -1391,7 +1391,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, ForceCoilsMessage& m ) ...@@ -1391,7 +1391,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, ForceCoilsMessage& m )
<< " bcnt=" << b2str(m.bcnt) << " bcnt=" << b2str(m.bcnt)
<< " data[" << (int)m.quant <<"]={ "; << " data[" << (int)m.quant <<"]={ ";
for( unsigned int i=0; i<m.bcnt; i++ ) for( ssize_t i=0; i<m.bcnt; i++ )
{ {
DataBits d(m.data[i]); DataBits d(m.data[i]);
os << "" << d << " "; os << "" << d << " ";
...@@ -1539,7 +1539,7 @@ ModbusMessage WriteOutputMessage::transport_msg() ...@@ -1539,7 +1539,7 @@ ModbusMessage WriteOutputMessage::transport_msg()
// Создаём временно массив, переворачиваем байты // Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[quant]; ModbusData* dtmp = new ModbusData[quant];
for( unsigned int i=0; i<quant; i++ ) for( ssize_t i=0; i<quant; i++ )
dtmp[i] = SWAPSHORT(data[i]); dtmp[i] = SWAPSHORT(data[i]);
// копируем данные // копируем данные
...@@ -1606,7 +1606,7 @@ void WriteOutputMessage::init( ModbusMessage& m ) ...@@ -1606,7 +1606,7 @@ void WriteOutputMessage::init( ModbusMessage& m )
memcpy(&crc,&(m.data[m.len-szCRC]),szCRC); memcpy(&crc,&(m.data[m.len-szCRC]),szCRC);
int count( bcnt/sizeof(ModbusData) ); int count( bcnt/sizeof(ModbusData) );
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
data[i] = SWAPSHORT(data[i]); data[i] = SWAPSHORT(data[i]);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -1651,7 +1651,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, WriteOutputMessage& m ) ...@@ -1651,7 +1651,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, WriteOutputMessage& m )
<< " bcnt=" << dat2str(m.bcnt) << " bcnt=" << dat2str(m.bcnt)
<< " data[" << (int)m.quant <<"]={ "; << " data[" << (int)m.quant <<"]={ ";
for( unsigned int i=0; i<m.quant; i++ ) for( ssize_t i=0; i<m.quant; i++ )
os << "" << dat2str(m.data[i]) << " "; os << "" << dat2str(m.data[i]) << " ";
os << "}"; os << "}";
...@@ -2178,7 +2178,7 @@ void DiagnosticMessage::init( ModbusMessage& m ) ...@@ -2178,7 +2178,7 @@ void DiagnosticMessage::init( ModbusMessage& m )
last +=sizeof(ModbusData)*count; last +=sizeof(ModbusData)*count;
// переворачиваем данные // переворачиваем данные
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
data[i] = SWAPSHORT(data[i]); data[i] = SWAPSHORT(data[i]);
memcpy(&crc,&(m.data[last]),szCRC); memcpy(&crc,&(m.data[last]),szCRC);
...@@ -2243,7 +2243,7 @@ ModbusMessage DiagnosticMessage::transport_msg() ...@@ -2243,7 +2243,7 @@ ModbusMessage DiagnosticMessage::transport_msg()
// Создаём временно массив, переворачиваем байты // Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[count]; ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]); dtmp[i] = SWAPSHORT(data[i]);
// копируем // копируем
...@@ -2294,7 +2294,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, DiagnosticMessage& m ) ...@@ -2294,7 +2294,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, DiagnosticMessage& m )
<< " subf=" << dat2str(m.subf) << " subf=" << dat2str(m.subf)
<< " data[" << m.count << "]={"; << " data[" << m.count << "]={";
for( unsigned int i=0; i<m.count; i++ ) for( ssize_t i=0; i<m.count; i++ )
os << dat2str(m.data[i]) << " "; os << dat2str(m.data[i]) << " ";
os << "}"; os << "}";
...@@ -2314,7 +2314,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, DiagnosticRetMessage& m ) ...@@ -2314,7 +2314,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, DiagnosticRetMessage& m )
<< " subf=" << dat2str(m.subf) << " subf=" << dat2str(m.subf)
<< " data[" << m.count << "]={"; << " data[" << m.count << "]={";
for( unsigned int i=0; i<m.count; i++ ) for( ssize_t i=0; i<m.count; i++ )
os << dat2str(m.data[i]) << " "; os << dat2str(m.data[i]) << " ";
os << "}"; os << "}";
...@@ -2440,7 +2440,7 @@ RDIObjectInfo::RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len ): ...@@ -2440,7 +2440,7 @@ RDIObjectInfo::RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len ):
{ {
val.reserve(len); val.reserve(len);
for( unsigned int i=0; i<len; i++ ) for( ssize_t i=0; i<len; i++ )
val.push_back( (char)dat[i] ); val.push_back( (char)dat[i] );
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -2738,7 +2738,7 @@ ModbusMessage JournalCommandRetMessage::transport_msg() ...@@ -2738,7 +2738,7 @@ ModbusMessage JournalCommandRetMessage::transport_msg()
// -------------------- // --------------------
// копирование с переворотом данных (для ModbusData) // копирование с переворотом данных (для ModbusData)
ModbusData* dtmp = new ModbusData[count]; ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]); dtmp[i] = SWAPSHORT(data[i]);
// копируем // копируем
...@@ -3240,7 +3240,7 @@ void ReadFileRecordMessage::init( ModbusMessage& m ) ...@@ -3240,7 +3240,7 @@ void ReadFileRecordMessage::init( ModbusMessage& m )
memcpy(&crc,&(m.data[m.len-szCRC]),szCRC); memcpy(&crc,&(m.data[m.len-szCRC]),szCRC);
count = bcnt/sizeof(SubRequest); count = bcnt/sizeof(SubRequest);
for( unsigned int i=0; i<count; i++ ) for( ssize_t i=0; i<count; i++ )
{ {
data[i].numfile = SWAPSHORT(data[i].numfile); data[i].numfile = SWAPSHORT(data[i].numfile);
data[i].numrec = SWAPSHORT(data[i].numrec); data[i].numrec = SWAPSHORT(data[i].numrec);
...@@ -3440,7 +3440,7 @@ ModbusMessage FileTransferRetMessage::transport_msg() ...@@ -3440,7 +3440,7 @@ ModbusMessage FileTransferRetMessage::transport_msg()
// копируем предварительный заголовок // копируем предварительный заголовок
ModbusData dhead[] = { numfile, numpacks, packet }; ModbusData dhead[] = { numfile, numpacks, packet };
for( unsigned int i=0; i<sizeof(dhead)/sizeof(ModbusData); i++ ) for( size_t i=0; i<sizeof(dhead)/sizeof(ModbusData); i++ )
dhead[i] = SWAPSHORT(dhead[i]); dhead[i] = SWAPSHORT(dhead[i]);
memcpy(&(mm.data[ind]),dhead,sizeof(dhead)); memcpy(&(mm.data[ind]),dhead,sizeof(dhead));
...@@ -3479,7 +3479,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, FileTransferRetMessage* m ...@@ -3479,7 +3479,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, FileTransferRetMessage* m
std::ostream& ModbusTCP::operator<<(std::ostream& os, MBAPHeader& m ) std::ostream& ModbusTCP::operator<<(std::ostream& os, MBAPHeader& m )
{ {
// m.swapdata(); // m.swapdata();
for( unsigned int i=0; i<sizeof(m); i++ ) for( size_t i=0; i<sizeof(m); i++ )
os << ((unsigned char*)(&m))[i]; os << ((unsigned char*)(&m))[i];
// m.swapdata(); // m.swapdata();
return os; return os;
......
############################################################################
# This file is part of the UniSet library #
############################################################################
noinst_LTLIBRARIES = libTCP.la
libTCP_la_SOURCES = UTCPStream.cc TCPCheck.cc
libTCP_la_CXXFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libTCP_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <sstream> #include <sstream>
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "PassiveTimer.h" #include "PassiveTimer.h"
#include "modbus/TCPCheck.h" #include "TCPCheck.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
using namespace std; using namespace std;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <errno.h> #include <errno.h>
#include <cstring> #include <cstring>
#include <cc++/socket.h> #include <cc++/socket.h>
#include "modbus/UTCPStream.h" #include "UTCPStream.h"
#include "PassiveTimer.h" #include "PassiveTimer.h"
#include "UniSetTypes.h" #include "UniSetTypes.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
#ifndef DEBUGEXTBUF_H
#define DEBUGEXTBUF_H
// Created by Lars Gullik Bj�nnes // Created by Lars Gullik Bj�nnes
// Copyright 1999 Lars Gullik Bj�nnes (larsbj@lyx.org) // Copyright 1999 Lars Gullik Bj�nnes (larsbj@lyx.org)
// Released into the public domain. // Released into the public domain.
...@@ -16,6 +19,7 @@ ...@@ -16,6 +19,7 @@
//#include "DebugStream.h" //#include "DebugStream.h"
#include "Debug.h" #include "Debug.h"
#include "Mutex.h"
//�Since the current C++ lib in egcs does not have a standard implementation //�Since the current C++ lib in egcs does not have a standard implementation
// of basic_streambuf and basic_filebuf we don't have to include this // of basic_streambuf and basic_filebuf we don't have to include this
...@@ -34,6 +38,7 @@ using std::ostream; ...@@ -34,6 +38,7 @@ using std::ostream;
using std::streambuf; using std::streambuf;
using std::streamsize; using std::streamsize;
using std::filebuf; using std::filebuf;
using std::stringbuf;
using std::cerr; using std::cerr;
using std::ios; using std::ios;
...@@ -127,6 +132,64 @@ private: ...@@ -127,6 +132,64 @@ private:
streambuf * sb2; streambuf * sb2;
}; };
/** A streambuf that sends the output to two different streambufs. These
can be any kind of streambufs.
*/
class threebuf : public streambuf {
public:
///
threebuf(streambuf * b1, streambuf * b2, streambuf * b3)
: streambuf(), sb1(b1), sb2(b2), sb3(b3) {}
protected:
#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
sb2->pubsync();
return sb1->pubsync();
}
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
sb2->sputn(p, n);
sb3->sputn(p, n);
return sb1->sputn(p, n);
}
///
virtual int_type overflow(int_type c = traits_type::eof()) {
sb2->sputc(c);
sb3->sputc(c);
return sb1->sputc(c);
}
#else
typedef char char_type;
typedef int int_type;
///
virtual int sync() {
sb2->sync();
sb3->sync();
return sb1->sync();
}
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
sb2->xsputn(p, n);
sb2->xsputn(p, n);
return sb1->xsputn(p, n);
}
///
virtual int_type overflow(int_type c = EOF) {
sb2->overflow(c);
sb3->owerflow(c);
return sb1->overflow(c);
}
#endif
private:
///
streambuf * sb1;
///
streambuf * sb2;
///
streambuf * sb3;
};
/// ///
class debugbuf : public streambuf { class debugbuf : public streambuf {
public: public:
...@@ -168,235 +231,92 @@ private: ...@@ -168,235 +231,92 @@ private:
streambuf * sb; streambuf * sb;
}; };
//-------------------------------------------------------------------------- ///
/// So that public parts of DebugStream does not need to know about filebuf class stringsigbuf : public streambuf {
struct DebugStream::debugstream_internal { public:
/// Used when logging to file. stringsigbuf():sb(new stringbuf())
filebuf fbuf; {
}; }
//--------------------------------------------------------------------------
/// Constructor, sets the debug level to t.
DebugStream::DebugStream(Debug::type t)
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf), internal(0),
show_datetime(true),
fname(""){}
//-------------------------------------------------------------------------- ~stringsigbuf()
/// Constructor, sets the log file to f, and the debug level to t. {
DebugStream::DebugStream(char const * f, Debug::type t) if( sb )
: ostream(new debugbuf(cerr.rdbuf())), {
dt(t), nullstream(new nullbuf), delete sb;
internal(new debugstream_internal), sb = 0;
show_datetime(true), }
fname("") }
{
internal->fbuf.open(f, ios::out|ios::app);
delete rdbuf(new teebuf(cerr.rdbuf(),
&internal->fbuf));
}
//--------------------------------------------------------------------------
DebugStream::~DebugStream() ///
{ stringsigbuf( stringbuf* b )
delete nullstream.rdbuf(0); // Without this we leak : streambuf(), sb(b) {}
delete rdbuf(0); // Without this we leak
delete internal;
}
//-------------------------------------------------------------------------- typedef sigc::signal<void,const std::string&> StrBufOverflow_Signal;
const DebugStream& DebugStream::operator=( const DebugStream& r ) inline StrBufOverflow_Signal signal_overflow(){ return s_overflow; }
{
if( r == *this )
return *this;
dt = r.dt; protected:
show_datetime = r.show_datetime; #ifdef MODERN_STL_STREAMS
fname = r.fname; ///
if( !r.fname.empty() ) virtual int sync() {
logFile(fname); UniSetTypes::uniset_rwmutex_wrlock l(mut);
return sb->pubsync();
return *this;
}
//--------------------------------------------------------------------------
/// Sets the debugstreams' logfile to f.
void DebugStream::logFile( const std::string& f )
{
fname = f;
if (internal) {
internal->fbuf.close();
} else {
internal = new debugstream_internal;
} }
internal->fbuf.open(f.c_str(), ios::out|ios::app);
delete rdbuf(new teebuf(cerr.rdbuf(), ///
&internal->fbuf)); virtual streamsize xsputn(char_type const * p, streamsize n) {
} UniSetTypes::uniset_rwmutex_wrlock l(mut);
//-------------------------------------------------------------------------- streamsize r = sb->sputn(p, n);
std::ostream & DebugStream::debug(Debug::type t) s_overflow.emit( sb->str() );
{ sb->str("");
if(dt & t) return r;
{
if( show_datetime )
printDateTime(t);
*this << "(" << std::setfill(' ') << std::setw(6) << t << "): "; // "):\t";
return *this;
} }
///
return nullstream; virtual int_type overflow(int_type c = traits_type::eof()) {
} int_type r = sb->sputc(c);
//-------------------------------------------------------------------------- if( r == '\n' )
std::ostream& DebugStream::operator()(Debug::type t) {
{ UniSetTypes::uniset_rwmutex_wrlock l(mut);
if(dt & t) s_overflow.emit( sb->str() );
return *this; sb->str("");
}
return nullstream; return r;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDate(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << brk
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << brk
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900;
} }
#else
return nullstream; typedef char char_type;
} typedef int int_type;
//-------------------------------------------------------------------------- ///
std::ostream& DebugStream::printTime(Debug::type t, char brk) virtual int sync() {
{ return sb->sync();
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_hour << brk
<< std::setw(2) << std::setfill('0') << tms->tm_min << brk
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
} }
///
return nullstream; virtual streamsize xsputn(char_type const * p, streamsize n) {
} return sb->xsputn(p, n);
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDateTime(Debug::type t)
{
if(dt & t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << "/"
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << "/"
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900 << " "
<< std::setw(2) << std::setfill('0') << tms->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_min << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
} }
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::pos(int x, int y)
{
if( !dt )
return nullstream;
return *this << "\033[" << y << ";" << x << "f";
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#ifdef TEST_DEBUGSTREAM
// Example debug stream
DebugStream debugstream;
int main(int, char **)
{
/**
I have been running some tests on this to see how much overhead
this kind of permanent debug code has. My conclusion is: not
much. In all, but the most time critical code, this will have
close to no impact at all.
In the tests that I have run the use of
if (debugstream.debugging(DebugStream::INFO))
debugstream << "some debug\n";
has close to no overhead when the debug level is not
DebugStream::INFO.
The overhead for virtual int_type overflow(int_type c = EOF) {
debugstream.debug(DebugStream::INFO) << "some debug\n"; int_type r = sb->overflow(c);
is also very small when the debug level is not if( r == '\n' )
DebugStream::INFO. However the overhead for this will increase {
if complex debugging information is output. UniSetTypes::uniset_rwmutex_wrlock l(mut);
s_overflow.emit( sb->str() );
The overhead when the debug level is DebugStream::INFO can be sb->str("");
significant, but since we then are running in debug mode it is }
of no concern. return r;
Why should we use this instead of the class Error that we already
have? First of all it uses C++ iostream and constructs, secondly
it will be a lot easier to output the debug info that we need
without a lot of manual conversions, thirdly we can now use
iomanipulators and the complete iostream formatting functions.
pluss it will work for all types that have a operator<<
defined, and can be used in functors that take a ostream & as
parameter. And there should be less need for temporary objects.
And one nice bonus is that we get a log file almost for
free.
Some of the names are of course open to modifications. I will try
to use the names we already use in LyX.
*/
// Just a few simple debugs to show how it can work.
debugstream << "Debug level set to Debug::NONE\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.level(Debug::value("INFO"));
debugstream << "Setting debug level to Debug::INFO\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.addLevel(Debug::type(Debug::CRIT |
Debug::WARN));
debugstream << "Adding Debug::CRIT and Debug::WARN\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.delLevel(Debug::INFO);
debugstream << "Removing Debug::INFO\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.logFile("logfile");
debugstream << "Setting logfile to \"logfile\"\n";
debugstream << "Value: " << 123 << " " << "12\n";
int i = 0;
int * p = new int;
// note: the (void*) is needed on g++ 2.7.x since it does not
// support partial specialization. In egcs this should not be
// needed.
debugstream << "automatic " << &i
<< ", free store " << p << endl;
delete p;
/*
for (int j = 0; j < 200000; ++j) {
DebugStream tmp;
tmp << "Test" << endl;
} }
*/
}
#endif #endif
private:
///
StrBufOverflow_Signal s_overflow;
stringbuf* sb;
UniSetTypes::uniset_rwmutex mut;
};
//--------------------------------------------------------------------------
/// So that public parts of DebugStream does not need to know about filebuf
struct DebugStream::debugstream_internal {
/// Used when logging to file.
filebuf fbuf;
stringsigbuf sbuf;
nullbuf nbuf;
};
//--------------------------------------------------------------------------
#endif
\ No newline at end of file
// Created by Lars Gullik Bj�nnes
// Copyright 1999 Lars Gullik Bj�nnes (larsbj@lyx.org)
// Released into the public domain.
// Primarily developed for use in the LyX Project http://www.lyx.org/
// but should be adaptable to any project.
// (c) 2002 adapted for UniSet by Lav, GNU GPL license
//#define TEST_DEBUGSTREAM
#ifdef __GNUG__
#pragma implementation
#endif
//#include "DebugStream.h"
#include "Debug.h"
#include "Mutex.h"
//�Since the current C++ lib in egcs does not have a standard implementation
// of basic_streambuf and basic_filebuf we don't have to include this
// header.
//#define MODERN_STL_STREAMS
#ifdef MODERN_STL_STREAMS
#include <fstream>
#endif
#include <iostream>
#include <sstream>
#include <iomanip>
#include <time.h>
#include <iomanip>
#include "DebugExtBuf.h"
using std::ostream;
using std::streambuf;
using std::streamsize;
using std::filebuf;
using std::stringbuf;
using std::cerr;
using std::ios;
//--------------------------------------------------------------------------
/// Constructor, sets the debug level to t.
DebugStream::DebugStream(Debug::type t)
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf), internal(new debugstream_internal),
show_datetime(true),
fname(""),
logname("")
{
delete rdbuf(new teebuf(cerr.rdbuf(),&internal->sbuf));
internal->sbuf.signal_overflow().connect(sigc::mem_fun(*this, &DebugStream::sbuf_overflow));
}
//--------------------------------------------------------------------------
/// Constructor, sets the log file to f, and the debug level to t.
DebugStream::DebugStream(char const * f, Debug::type t, bool truncate )
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf),
internal(new debugstream_internal),
show_datetime(true),
fname(""),
logname("")
{
std::ios_base::openmode mode = ios::out;
mode |= truncate ? ios::trunc : ios::app;
internal->fbuf.open(f, mode);
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf,&internal->sbuf));
internal->sbuf.signal_overflow().connect(sigc::mem_fun(*this, &DebugStream::sbuf_overflow));
}
//--------------------------------------------------------------------------
void DebugStream::sbuf_overflow( const std::string& s )
{
s_stream.emit(s);
}
//--------------------------------------------------------------------------
DebugStream::~DebugStream()
{
delete nullstream.rdbuf(0); // Without this we leak
delete rdbuf(0); // Without this we leak
delete internal;
}
//--------------------------------------------------------------------------
const DebugStream& DebugStream::operator=( const DebugStream& r )
{
if( r == *this )
return *this;
dt = r.dt;
show_datetime = r.show_datetime;
fname = r.fname;
if( !r.fname.empty() )
logFile(fname);
// s_stream = r.s_stream;
return *this;
}
//--------------------------------------------------------------------------
/// Sets the debugstreams' logfile to f.
void DebugStream::logFile( const std::string& f, bool truncate )
{
fname = f;
if( internal ) {
internal->fbuf.close();
} else {
internal = new debugstream_internal;
}
if( !f.empty() )
{
std::ios_base::openmode mode = ios::out;
mode |= truncate ? ios::trunc : ios::app;
internal->fbuf.open(f.c_str(), mode);
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf,&internal->sbuf));
}
else
delete rdbuf(new teebuf(cerr.rdbuf(),&internal->sbuf));
}
//--------------------------------------------------------------------------
std::ostream & DebugStream::debug(Debug::type t)
{
if(dt & t)
{
if( show_datetime )
printDateTime(t);
*this << "(" << std::setfill(' ') << std::setw(6) << t << "): "; // "):\t";
return *this;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::operator()(Debug::type t)
{
if(dt & t)
return *this;
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDate(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << brk
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << brk
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printTime(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_hour << brk
<< std::setw(2) << std::setfill('0') << tms->tm_min << brk
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDateTime(Debug::type t)
{
if(dt & t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << "/"
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << "/"
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900 << " "
<< std::setw(2) << std::setfill('0') << tms->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_min << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::pos(int x, int y)
{
if( !dt )
return nullstream;
return *this << "\033[" << y << ";" << x << "f";
}
//--------------------------------------------------------------------------
DebugStream::StreamEvent_Signal DebugStream::signal_stream_event()
{
return s_stream;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#ifdef TEST_DEBUGSTREAM
// Example debug stream
DebugStream debugstream;
int main(int, char **)
{
/**
I have been running some tests on this to see how much overhead
this kind of permanent debug code has. My conclusion is: not
much. In all, but the most time critical code, this will have
close to no impact at all.
In the tests that I have run the use of
if (debugstream.debugging(DebugStream::INFO))
debugstream << "some debug\n";
has close to no overhead when the debug level is not
DebugStream::INFO.
The overhead for
debugstream.debug(DebugStream::INFO) << "some debug\n";
is also very small when the debug level is not
DebugStream::INFO. However the overhead for this will increase
if complex debugging information is output.
The overhead when the debug level is DebugStream::INFO can be
significant, but since we then are running in debug mode it is
of no concern.
Why should we use this instead of the class Error that we already
have? First of all it uses C++ iostream and constructs, secondly
it will be a lot easier to output the debug info that we need
without a lot of manual conversions, thirdly we can now use
iomanipulators and the complete iostream formatting functions.
pluss it will work for all types that have a operator<<
defined, and can be used in functors that take a ostream & as
parameter. And there should be less need for temporary objects.
And one nice bonus is that we get a log file almost for
free.
Some of the names are of course open to modifications. I will try
to use the names we already use in LyX.
*/
// Just a few simple debugs to show how it can work.
debugstream << "Debug level set to Debug::NONE\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.level(Debug::value("INFO"));
debugstream << "Setting debug level to Debug::INFO\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.addLevel(Debug::type(Debug::CRIT |
Debug::WARN));
debugstream << "Adding Debug::CRIT and Debug::WARN\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.delLevel(Debug::INFO);
debugstream << "Removing Debug::INFO\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.logFile("logfile");
debugstream << "Setting logfile to \"logfile\"\n";
debugstream << "Value: " << 123 << " " << "12\n";
int i = 0;
int * p = new int;
// note: the (void*) is needed on g++ 2.7.x since it does not
// support partial specialization. In egcs this should not be
// needed.
debugstream << "automatic " << &i
<< ", free store " << p << endl;
delete p;
/*
for (int j = 0; j < 200000; ++j) {
DebugStream tmp;
tmp << "Test" << endl;
}
*/
}
#endif
#include "DebugExtBuf.h"
#include "LogAgregator.h"
// -------------------------------------------------------------------------
LogAgregator::LogAgregator( char const * f, Debug::type t ):
DebugStream(f,t)
{
delete rdbuf(new teebuf(&internal->fbuf,&internal->sbuf));
}
// -------------------------------------------------------------------------
LogAgregator::LogAgregator( Debug::type t ):
DebugStream(t)
{
delete rdbuf(new teebuf(&internal->nbuf,&internal->sbuf));
}
// -------------------------------------------------------------------------
void LogAgregator::logFile( const std::string& f )
{
DebugStream::logFile(f);
if( !f.empty() )
delete rdbuf(new teebuf(&internal->fbuf,&internal->sbuf));
else
delete rdbuf(new teebuf(&internal->nbuf,&internal->sbuf));
}
// -------------------------------------------------------------------------
LogAgregator::~LogAgregator()
{
}
// -------------------------------------------------------------------------
void LogAgregator::logOnEvent( const std::string& s )
{
(*this) << s;
}
// -------------------------------------------------------------------------
void LogAgregator::add( DebugStream& l )
{
l.signal_stream_event().connect( sigc::mem_fun(this, &LogAgregator::logOnEvent) );
for( LogList::iterator i=llst.begin(); i!=llst.end(); i++ )
{
if( &l == i->log )
return;
}
llst.push_back(&l);
}
// -------------------------------------------------------------------------
void LogAgregator::addLevel( const std::string& logname, Debug::type t )
{
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
{
i.log->addLevel(t);
break;
}
}
}
// -------------------------------------------------------------------------
void LogAgregator::delLevel( const std::string& logname, Debug::type t )
{
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
{
i.log->delLevel(t);
break;
}
}
}
// -------------------------------------------------------------------------
void LogAgregator::level( const std::string& logname, Debug::type t )
{
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
{
i.log->level(t);
break;
}
}
}
// -------------------------------------------------------------------------
DebugStream* LogAgregator::getLog( const std::string& logname )
{
if( logname.empty() )
return 0;
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
return i.log;
}
return 0;
}
// -------------------------------------------------------------------------
LogAgregator::LogInfo LogAgregator::getLogInfo( const std::string& logname )
{
if( logname.empty() )
return LogInfo();
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
return i;
}
return LogInfo();
}
// -------------------------------------------------------------------------
#include <string.h>
#include <errno.h>
#include <iostream>
#include <sstream>
#include "Exceptions.h"
#include "LogReader.h"
#include "UniSetTypes.h"
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -------------------------------------------------------------------------
LogReader::LogReader():
tcp(0),
iaddr(""),
cmdonly(false)
{
}
// -------------------------------------------------------------------------
LogReader::~LogReader()
{
if( isConnection() )
disconnect();
}
// -------------------------------------------------------------------------
void LogReader::connect( const std::string& addr, ost::tpport_t _port, timeout_t msec )
{
ost::InetAddress ia(addr.c_str());
connect(ia,_port,msec);
}
// -------------------------------------------------------------------------
void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t msec )
{
if( tcp )
{
(*tcp) << endl;
disconnect();
delete tcp;
tcp = 0;
}
// if( !tcp )
// {
ostringstream s;
s << addr;
iaddr = s.str();
port = _port;
if( rlog.is_info() )
rlog.info() << "(LogReader): connect to " << iaddr << ":" << port << endl;
ost::Thread::setException(ost::Thread::throwException);
try
{
tcp = new UTCPStream();
tcp->create(iaddr,port,true,500);
tcp->setTimeout(msec);
tcp->setKeepAlive(true);
}
catch( std::exception& e )
{
if( rlog.debugging(Debug::CRIT) )
{
ostringstream s;
s << "(LogReader): connection " << s.str() << " error: " << e.what();
rlog.crit() << s.str() << std::endl;
}
delete tcp;
tcp = 0;
}
catch( ... )
{
if( rlog.debugging(Debug::CRIT) )
{
ostringstream s;
s << "(LogReader): connection " << s.str() << " error: catch ...";
rlog.crit() << s.str() << std::endl;
}
}
// }
}
// -------------------------------------------------------------------------
void LogReader::disconnect()
{
if( !tcp )
return;
if( rlog.is_info() )
rlog.info() << iaddr << "(LogReader): disconnect." << endl;
tcp->disconnect();
delete tcp;
tcp = 0;
}
// -------------------------------------------------------------------------
bool LogReader::isConnection()
{
return tcp && tcp->isConnected();
}
// -------------------------------------------------------------------------
void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServerTypes::Command cmd, int data, const std::string& logname, bool verbose )
{
LogServerTypes::lsMessage msg;
msg.cmd = cmd;
msg.data = data;
msg.setLogName(logname);
readlogs(_addr,_port,msg,verbose );
}
// -------------------------------------------------------------------------
void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServerTypes::lsMessage& msg, bool verbose )
{
timeout_t inTimeout = 10000;
timeout_t outTimeout = 6000;
timeout_t reconDelay = 5000;
char buf[100001];
if( verbose )
rlog.addLevel(Debug::ANY);
bool send_ok = false;
while( true )
{
if( !isConnection() )
connect(_addr,_port,reconDelay);
if( !isConnection() )
{
rlog.warn() << "**** connection timeout.." << endl;
msleep(reconDelay);
continue;
}
if( !send_ok && msg.cmd != LogServerTypes::cmdNOP )
{
if( tcp->isPending(ost::Socket::pendingOutput,outTimeout) )
{
rlog.info() << "** send command: logname='" << msg.logname << "' cmd='" << msg.cmd << "' data='" << msg.data << "'" << endl;
// LogServerTypes::lsMessage msg;
// msg.cmd = cmd;
// msg.data = data;
for( size_t i=0; i<sizeof(msg); i++ )
(*tcp) << ((unsigned char*)(&msg))[i];
tcp->sync();
send_ok = true;
}
else
rlog.warn() << "**** SEND COMMAND ('" << msg.cmd << "' FAILED!" << endl;
if( cmdonly )
{
disconnect();
return;
}
}
while( !cmdonly && tcp->isPending(ost::Socket::pendingInput,inTimeout) )
{
int n = tcp->peek( buf,sizeof(buf)-1 );
if( n > 0 )
{
tcp->read(buf,n);
buf[n] = '\0';
cout << buf;
}
else
break;
}
rlog.warn() << "...connection timeout..." << endl;
send_ok = false; // ??!! делать ли?
disconnect();
}
if( isConnection() )
disconnect();
}
// -------------------------------------------------------------------------
#include <sstream>
#include "LogServer.h"
#include "UniSetTypes.h"
#include "Exceptions.h"
#include "LogSession.h"
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -------------------------------------------------------------------------
LogServer::~LogServer()
{
cancelled = true;
if( thr )
{
thr->stop();
if( thr->isRunning() )
thr->join();
delete thr;
}
{
// uniset_rwmutex_wrlock l(mutSList);
for( auto& i: slist )
{
if( i->isRunning() )
delete i;
}
}
delete tcp;
}
// -------------------------------------------------------------------------
LogServer::LogServer( std::ostream& os ):
timeout(TIMEOUT_INF),
sessTimeout(3600000),
cmdTimeout(2000),
outTimeout(2000),
cancelled(false),
thr(0),
tcp(0),
elog(0),
oslog(&os)
{
}
// -------------------------------------------------------------------------
LogServer::LogServer( DebugStream& log ):
timeout(TIMEOUT_INF),
sessTimeout(3600000),
cmdTimeout(2000),
outTimeout(2000),
cancelled(false),
thr(0),
tcp(0),
elog(&log),
oslog(0)
{
}
// -------------------------------------------------------------------------
LogServer::LogServer():
timeout(TIMEOUT_INF),
sessTimeout(3600000),
cmdTimeout(2000),
outTimeout(2000),
cancelled(false),
thr(0),
tcp(0),
elog(0)
{
}
// -------------------------------------------------------------------------
void LogServer::run( const std::string& addr, ost::tpport_t port, bool thread )
{
try
{
ost::InetAddress iaddr(addr.c_str());
tcp = new ost::TCPSocket(iaddr,port);
}
catch( ost::Socket *socket )
{
ost::tpport_t port;
int errnum = socket->getErrorNumber();
ost::InetAddress saddr = (ost::InetAddress)socket->getPeer(&port);
ostringstream err;
err << "socket error " << saddr.getHostname() << ":" << port << " = " << errnum;
if( errnum == ost::Socket::errBindingFailed )
err << "bind failed; port busy" << endl;
else
err << "client socket failed" << endl;
throw SystemError( err.str() );
}
if( !thread )
work();
else
{
thr = new ThreadCreator<LogServer>(this, &LogServer::work);
thr->start();
}
}
// -------------------------------------------------------------------------
void LogServer::work()
{
cancelled = false;
while( !cancelled )
{
try
{
while( !cancelled && tcp->isPendingConnection(timeout) )
{
LogSession* s = new LogSession(*tcp, elog, sessTimeout, cmdTimeout, outTimeout);
{
uniset_rwmutex_wrlock l(mutSList);
slist.push_back(s);
}
s->connectFinalSession( sigc::mem_fun(this, &LogServer::sessionFinished) );
s->detach();
}
}
catch( ost::Socket *socket )
{
ost::tpport_t port;
int errnum = socket->getErrorNumber();
ost::InetAddress saddr = (ost::InetAddress)socket->getPeer(&port);
cerr << "socket error " << saddr.getHostname() << ":" << port << " = " << errnum << endl;
if( errnum == ost::Socket::errBindingFailed )
{
cerr << "bind failed; port busy" << endl;
// ::exit(-1);
}
else
cerr << "client socket failed" << endl;
}
}
cerr << "*** LOG SERVER THREAD STOPPED.." << endl;
{
// uniset_rwmutex_wrlock l(mutSList);
for( auto& i: slist )
i->disconnect();
}
}
// -------------------------------------------------------------------------
void LogServer::sessionFinished( LogSession* s )
{
uniset_rwmutex_wrlock l(mutSList);
for( SessionList::iterator i=slist.begin(); i!=slist.end(); ++i )
{
if( (*i) == s )
{
slist.erase(i);
return;
}
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#include "LogServerTypes.h"
// -------------------------------------------------------------------------
using namespace std;
// -------------------------------------------------------------------------
std::ostream& LogServerTypes::operator<<(std::ostream& os, LogServerTypes::Command cmd )
{
switch( cmd )
{
case LogServerTypes::cmdSetLevel:
return os << "cmdSetLevel";
case LogServerTypes::cmdAddLevel:
return os << "cmdAddLevel";
case LogServerTypes::cmdDelLevel:
return os << "cmdDelLevel";
case LogServerTypes::cmdRotate:
return os << "cmdRotate";
case LogServerTypes::cmdOffLogFile:
return os << "cmdOffLogFile";
case LogServerTypes::cmdOnLogFile:
return os << "cmdOnLogFile";
default:
return os << "Unknown";
}
return os;
}
// -------------------------------------------------------------------------
std::ostream& LogServerTypes::operator<<(std::ostream& os, LogServerTypes::lsMessage& m )
{
return os << " magic=" << m.magic << " cmd=" << m.cmd << " data=" << m.data;
}
// -------------------------------------------------------------------------
void LogServerTypes::lsMessage::setLogName( const std::string& name )
{
size_t s = name.size()> MAXLOGNAME ? MAXLOGNAME : name.size();
memcpy( &logname, name.c_str(), s );
logname[s] = '\0';
}
// -------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <sstream>
#include <fcntl.h>
#include <errno.h>
#include <cstring>
#include <cc++/socket.h>
#include "LogSession.h"
#include "UniSetTypes.h"
#include "LogServerTypes.h"
#include "LogAgregator.h"
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -------------------------------------------------------------------------
LogSession::~LogSession()
{
cancelled = true;
if( isRunning() )
{
disconnect();
ost::Thread::join();
}
}
// -------------------------------------------------------------------------
LogSession::LogSession( ost::TCPSocket &server, DebugStream* _log, timeout_t _sessTimeout, timeout_t _cmdTimeout, timeout_t _outTimeout, timeout_t _delay ):
TCPSession(server),
peername(""),
caddr(""),
log(_log),
sessTimeout(_sessTimeout),
cmdTimeout(_cmdTimeout),
outTimeout(_outTimeout),
delayTime(_delay),
cancelled(false)
{
//slog.addLevel(Debug::ANY);
log->signal_stream_event().connect( sigc::mem_fun(this, &LogSession::logOnEvent) );
}
// -------------------------------------------------------------------------
void LogSession::logOnEvent( const std::string& s )
{
uniset_rwmutex_wrlock l(mLBuf);
lbuf.push_back(s);
}
// -------------------------------------------------------------------------
void LogSession::run()
{
if( cancelled )
return;
{
ost::tpport_t p;
ost::InetAddress iaddr = getIPV4Peer(&p);
// resolve..
caddr = string( iaddr.getHostname() );
ostringstream s;
s << iaddr << ":" << p;
peername = s.str();
}
if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): run thread of sessions.." << endl;
ptSessionTimeout.setTiming(sessTimeout);
setKeepAlive(true);
// setTimeout(sessTimeout);
// Команды могут посылаться только в начале сессии..
if( isPending(Socket::pendingInput, cmdTimeout) )
{
LogServerTypes::lsMessage msg;
// проверяем канал..(если данных нет, значит "клиент отвалился"...
if( peek( (void*)(&msg),sizeof(msg)) > 0 )
{
ssize_t ret = readData( &msg,sizeof(msg) );
if( ret!=sizeof(msg) || msg.magic!=LogServerTypes::MAGICNUM )
slog.warn() << peername << "(run): BAD MESSAGE..." << endl;
else
{
slog.info() << peername << "(run): receive command: '" << msg.cmd << "'" << endl;
string cmdLogName(msg.logname);
DebugStream* cmdlog = log;
string logfile(log->getLogFile());
if( !cmdLogName.empty () )
{
LogAgregator* lag = dynamic_cast<LogAgregator*>(log);
if( lag )
{
LogAgregator::LogInfo inf = lag->getLogInfo(cmdLogName);
if( inf.log )
{
cmdlog = inf.log;
logfile = inf.logfile;
}
else
{
// если имя задали, но такого лога не нашлось
// то игнорируем команду
cmdlog = 0;
logfile = "";
}
}
else
{
// если имя лога задали, а оно не совпадает с текущим
// игнорируем команду
if( log->getLogFile() != cmdLogName )
{
cmdlog = 0;
logfile = "";
}
}
}
// обрабатываем команды только если нашли log
if( cmdlog )
{
// Обработка команд..
// \warning Работа с логом ведётся без mutex-а, хотя он разделяется отдельными потоками
switch( msg.cmd )
{
case LogServerTypes::cmdSetLevel:
cmdlog->level( (Debug::type)msg.data );
break;
case LogServerTypes::cmdAddLevel:
cmdlog->addLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdDelLevel:
cmdlog->delLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdRotate:
if( !logfile.empty() )
cmdlog->logFile(logfile,true);
break;
case LogServerTypes::cmdOffLogFile:
{
if( !logfile.empty() )
cmdlog->logFile("");
}
break;
case LogServerTypes::cmdOnLogFile:
{
if( !logfile.empty() )
cmdlog->logFile(logfile);
}
break;
default:
slog.warn() << peername << "(run): Unknown command '" << msg.cmd << "'" << endl;
break;
}
}
}
}
}
cancelled = false;
while( !cancelled && isConnected() ) // !ptSessionTimeout.checkTime()
{
// проверка только ради проверки "целостности" соединения
if( isPending(Socket::pendingInput, 10) )
{
char buf[10];
// проверяем канал..(если данных нет, значит "клиент отвалился"...
if( peek(buf,sizeof(buf)) <=0 )
break;
}
if( isPending(Socket::pendingOutput, outTimeout) )
{
//slog.info() << peername << "(run): send.." << endl;
// ptSessionTimeout.reset();
// чтобы не застревать на посылке в сеть..
// делаем через промежуточный буффер (stringstream)
ostringstream sbuf;
bool send = false;
{
uniset_rwmutex_wrlock l(mLBuf);
if( !lbuf.empty() )
{
slog.info() << peername << "(run): send messages.." << endl;
while( !lbuf.empty() )
{
sbuf << lbuf.front();
lbuf.pop_front();
}
send = true;
}
}
if( send )
{
*tcp() << sbuf.str();
tcp()->sync();
}
// чтобы постоянно не проверять... (надо переделать на condition)
sleep(delayTime);
}
}
if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): stop thread of sessions..disconnect.." << endl;
disconnect();
if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): thread stopping..." << endl;
}
// -------------------------------------------------------------------------
void LogSession::final()
{
tcp()->sync();
slFin(this);
delete this;
}
// -------------------------------------------------------------------------
void LogSession::connectFinalSession( FinalSlot sl )
{
slFin = sl;
}
// ---------------------------------------------------------------------
############################################################################
# This file is part of the UniSet library #
############################################################################
noinst_LTLIBRARIES = libLog.la
libLog_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libLog_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libLog_la_SOURCES = DebugStream.cc Debug.cc LogServerTypes.cc LogServer.cc LogSession.cc LogReader.cc LogAgregator.cc
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
# This file is part of the UniSet library # # This file is part of the UniSet library #
############################################################################ ############################################################################
SUBDIRS=ObjectRepository Processes Interfaces Timers Services Various Communications SUBDIRS=ObjectRepository Processes Interfaces Timers Services Various Communications Log
...@@ -225,10 +225,10 @@ const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const ObjectId id ) ...@@ -225,10 +225,10 @@ const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const ObjectId id )
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const std::string& name ) const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const std::string& name )
{ {
auto it = mok.find(name); auto it = mok.find(name);
if( it != mok.end() ) if( it != mok.end() )
return getObjectInfo(it->second); return getObjectInfo(it->second);
return NULL; return NULL;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -48,7 +48,7 @@ using namespace std; ...@@ -48,7 +48,7 @@ using namespace std;
В этом обработчике происходит вызов UniSetActivator::oaDestroy(int signo) для фактического В этом обработчике происходит вызов UniSetActivator::oaDestroy(int signo) для фактического
завершения работы и заказывается сигнал SIG_ALRM на время TERMINATE_TIMEOUT, завершения работы и заказывается сигнал SIG_ALRM на время TERMINATE_TIMEOUT,
c обработчиком UniSetActivator::finishterm в котором происходит c обработчиком UniSetActivator::finishterm в котором происходит
"надежное" прибивание текущего процесса (raise(SIGKILL)). Это сделано на тот случай, если "надежное" прибивание текущего процесса (kill(getpid(),SIGKILL)). Это сделано на тот случай, если
в oaDestroy произойдет зависание. в oaDestroy произойдет зависание.
*/ */
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -140,7 +140,7 @@ void UniSetActivator::init() ...@@ -140,7 +140,7 @@ void UniSetActivator::init()
UniSetActivator::~UniSetActivator() UniSetActivator::~UniSetActivator()
{ {
if(!procterm ) if( !procterm )
{ {
ulogsys << myname << "(destructor): ..."<< endl << flush; ulogsys << myname << "(destructor): ..."<< endl << flush;
if( !omDestroy ) if( !omDestroy )
...@@ -153,7 +153,27 @@ UniSetActivator::~UniSetActivator() ...@@ -153,7 +153,27 @@ UniSetActivator::~UniSetActivator()
} }
if( orbthr ) if( orbthr )
{
orbthr->stop();
if( orbthr->isRunning() )
orbthr->join();
delete orbthr; delete orbthr;
orbthr = 0;
}
#if 0
try
{
if( !CORBA::is_nil(orb) )
{
ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
orb->destroy();
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
}
}
catch(...){}
#endif
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -170,30 +190,64 @@ void UniSetActivator::oaDestroy(int signo) ...@@ -170,30 +190,64 @@ void UniSetActivator::oaDestroy(int signo)
ulogsys << myname << "(oaDestroy): terminate ok. " << endl; ulogsys << myname << "(oaDestroy): terminate ok. " << endl;
try try
{ {
stop(); stop();
} }
catch(...){} catch(...){}
try
{
deactivateObject();
}
catch(...){}
ulogsys << myname << "(oaDestroy): pman deactivate... " << endl; ulogsys << myname << "(oaDestroy): pman deactivate... " << endl;
pman->deactivate(false,true); pman->deactivate(false,true);
ulogsys << myname << "(oaDestroy): pman deactivate ok. " << endl; ulogsys << myname << "(oaDestroy): pman deactivate ok. " << endl;
ulogsys << myname << "(oaDestroy): orb destroy... " << endl; ulogsys << myname << "(oaDestroy): orbthr=" << orbthr << endl;
try if( orbthr )
{ {
orb->destroy(); try
{
ulogsys << myname << "(oaDestroy): orb thread stop... " << endl;
orbthr->stop();
if( orbthr->isRunning() )
orbthr->join();
ulogsys << myname << "(oaDestroy): orb thread stop ok. " << endl;
}
catch(...){}
} }
catch(...){}
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl; try
{
ulogsys << myname << "(stop):: shutdown orb... "<<endl;
orb->shutdown(false);
}
catch(...){}
ulogsys << myname << "(stop): shutdown ok."<< endl;
#if 0
try
{
if( !CORBA::is_nil(orb) )
{
ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
orb->destroy();
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
}
}
catch(...){}
#endif
/*
if( orbthr ) if( orbthr )
{ {
delete orbthr; delete orbthr;
orbthr = 0; orbthr = 0;
} }
*/
} }
// waittermMutex.unlock(); // waittermMutex.unlock();
} }
...@@ -225,7 +279,7 @@ void UniSetActivator::run(bool thread) ...@@ -225,7 +279,7 @@ void UniSetActivator::run(bool thread)
pman->activate(); pman->activate();
msleep(50); msleep(50);
set_signals(true); set_signals(true);
if( thread ) if( thread )
{ {
uinfo << myname << "(run): запускаемся с созданием отдельного потока... "<< endl; uinfo << myname << "(run): запускаемся с созданием отдельного потока... "<< endl;
...@@ -266,16 +320,15 @@ void UniSetActivator::stop() ...@@ -266,16 +320,15 @@ void UniSetActivator::stop()
ulogsys << myname << "(stop): discard request ok."<< endl; ulogsys << myname << "(stop): discard request ok."<< endl;
/* #if 1
try try
{ {
ulogsys << myname << "(stop):: shutdown orb... "<<endl; ulogsys << myname << "(stop):: shutdown orb... "<<endl;
orb->shutdown(false); orb->shutdown(true);
} }
catch(...){} catch(...){}
ulogsys << myname << "(stop): shutdown ok."<< endl; ulogsys << myname << "(stop): shutdown ok."<< endl;
*/ #endif
} }
} }
...@@ -283,7 +336,7 @@ void UniSetActivator::stop() ...@@ -283,7 +336,7 @@ void UniSetActivator::stop()
void UniSetActivator::work() void UniSetActivator::work()
{ {
ulogsys << myname << "(work): запускаем orb на обработку запросов..."<< endl; ulogsys << myname << "(work): запускаем orb на обработку запросов...(orbthr=" << orbthr << ")" << endl;
try try
{ {
if( orbthr ) if( orbthr )
...@@ -313,17 +366,17 @@ void UniSetActivator::work() ...@@ -313,17 +366,17 @@ void UniSetActivator::work()
ucrit << myname << "(work): catch ..." << endl; ucrit << myname << "(work): catch ..." << endl;
} }
ulogsys << myname << "(work): orb стоп!!!"<< endl; ulogsys << myname << "(work): orb thread stopped!" << endl;
/*
ulogsys << myname << "(oaDestroy): orb destroy... " << endl; ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
try try
{ {
orb->destroy(); orb->destroy();
} }
catch(...){} catch(...){}
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl; ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
*/
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void UniSetActivator::getinfo() void UniSetActivator::getinfo()
...@@ -356,7 +409,7 @@ void UniSetActivator::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -356,7 +409,7 @@ void UniSetActivator::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname = ulog.getLogFile(); string fname = ulog.getLogFile();
if( !fname.empty() ) if( !fname.empty() )
{ {
ulog.logFile(fname.c_str()); ulog.logFile(fname.c_str(),true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << endl; ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << endl;
} }
} }
...@@ -364,18 +417,8 @@ void UniSetActivator::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -364,18 +417,8 @@ void UniSetActivator::sysCommand( const UniSetTypes::SystemMessage *sm )
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/*
void UniSetActivator::sig_child(int signo)
{
ulogsys << gActivator->getName() << "(sig_child): дочерний процесс закончил работу...(sig=" << signo << ")" << endl;
while( waitpid(-1, 0, WNOHANG) > 0);
}
*/
// ------------------------------------------------------------------------------------------
void UniSetActivator::set_signals(bool ask) void UniSetActivator::set_signals(bool ask)
{ {
struct sigaction act, oact; struct sigaction act, oact;
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
sigemptyset(&oact.sa_mask); sigemptyset(&oact.sa_mask);
...@@ -397,7 +440,7 @@ void UniSetActivator::set_signals(bool ask) ...@@ -397,7 +440,7 @@ void UniSetActivator::set_signals(bool ask)
act.sa_handler = terminated; act.sa_handler = terminated;
else else
act.sa_handler = SIG_DFL; act.sa_handler = SIG_DFL;
sigaction(SIGINT, &act, &oact); sigaction(SIGINT, &act, &oact);
sigaction(SIGTERM, &act, &oact); sigaction(SIGTERM, &act, &oact);
sigaction(SIGABRT, &act, &oact); sigaction(SIGABRT, &act, &oact);
...@@ -419,10 +462,15 @@ void UniSetActivator::finishterm( int signo ) ...@@ -419,10 +462,15 @@ void UniSetActivator::finishterm( int signo )
sigset(SIGALRM, SIG_DFL); sigset(SIGALRM, SIG_DFL);
doneterm = 1; doneterm = 1;
raise(SIGKILL); kill(getpid(),SIGKILL);
} }
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
UniSetActivator::TerminateEvent_Signal UniSetActivator::signal_terminate_event()
{
return s_term;
}
// ------------------------------------------------------------------------------------------
void UniSetActivator::terminated( int signo ) void UniSetActivator::terminated( int signo )
{ {
if( !signo || doneterm || !gActivator || procterm ) if( !signo || doneterm || !gActivator || procterm )
...@@ -447,17 +495,24 @@ void UniSetActivator::terminated( int signo ) ...@@ -447,17 +495,24 @@ void UniSetActivator::terminated( int signo )
alarm(TERMINATE_TIMEOUT); alarm(TERMINATE_TIMEOUT);
sigrelse(SIGALRM); sigrelse(SIGALRM);
if( gActivator ) if( gActivator )
{
ulogsys << ( gActivator ? gActivator->getName() : "" ) << "(terminated): call oaDestroy.." << endl;
gActivator->oaDestroy(SIGNO); // gActivator->term(SIGNO); gActivator->oaDestroy(SIGNO); // gActivator->term(SIGNO);
}
doneterm = 1; doneterm = 1;
ulogsys << ( gActivator ? gActivator->getName() : "" ) << "(terminated): завершаемся..."<< endl<< flush; ulogsys << ( gActivator ? gActivator->getName() : "" ) << "(terminated): завершаемся..."<< endl<< flush;
if( gActivator ) if( gActivator )
{
UniSetActivator::set_signals(false); UniSetActivator::set_signals(false);
delete gActivator;
gActivator = 0;
}
sigset(SIGALRM, SIG_DFL); sigset(SIGALRM, SIG_DFL);
raise(SIGNO); kill(getpid(), SIGNO );
} }
} }
} }
...@@ -467,6 +522,9 @@ void UniSetActivator::normalexit() ...@@ -467,6 +522,9 @@ void UniSetActivator::normalexit()
{ {
if( gActivator ) if( gActivator )
ulogsys << gActivator->getName() << "(default exit): good bye."<< endl << flush; ulogsys << gActivator->getName() << "(default exit): good bye."<< endl << flush;
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
} }
void UniSetActivator::normalterminate() void UniSetActivator::normalterminate()
...@@ -474,6 +532,9 @@ void UniSetActivator::normalterminate() ...@@ -474,6 +532,9 @@ void UniSetActivator::normalterminate()
if( gActivator ) if( gActivator )
ucrit << gActivator->getName() << "(default exception terminate): Никто не выловил исключение!!! Good bye."<< endl<< flush; ucrit << gActivator->getName() << "(default exception terminate): Никто не выловил исключение!!! Good bye."<< endl<< flush;
// abort(); // abort();
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void UniSetActivator::term( int signo ) void UniSetActivator::term( int signo )
...@@ -490,7 +551,7 @@ void UniSetActivator::term( int signo ) ...@@ -490,7 +551,7 @@ void UniSetActivator::term( int signo )
{ {
ulogsys << myname << "(term): вызываем sigterm()" << endl; ulogsys << myname << "(term): вызываем sigterm()" << endl;
sigterm(signo); sigterm(signo);
s_term.emit(signo);
ulogsys << myname << "(term): sigterm() ok." << endl; ulogsys << myname << "(term): sigterm() ok." << endl;
} }
catch(Exception& ex) catch(Exception& ex)
...@@ -506,7 +567,5 @@ void UniSetActivator::waitDestroy() ...@@ -506,7 +567,5 @@ void UniSetActivator::waitDestroy()
{ {
while( !doneterm && gActivator ) while( !doneterm && gActivator )
msleep(50); msleep(50);
gActivator = 0;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -115,9 +115,28 @@ UniSetManager::~UniSetManager() ...@@ -115,9 +115,28 @@ UniSetManager::~UniSetManager()
catch(...){} catch(...){}
try try
{ {
managers(deactiv); managers(deactiv);
} }
catch(...){} catch(...){}
for( auto& i: olist )
{
try
{
delete i;
}
catch(...){}
}
for( auto& i: mlist )
{
try
{
delete i;
}
catch(...){}
}
olist.clear(); olist.clear();
mlist.clear(); mlist.clear();
} }
...@@ -350,8 +369,18 @@ bool UniSetManager::deactivateObject() ...@@ -350,8 +369,18 @@ bool UniSetManager::deactivateObject()
void UniSetManager::sigterm( int signo ) void UniSetManager::sigterm( int signo )
{ {
sig=signo; sig=signo;
objects(term); try
managers(term); {
objects(term);
}
catch(...){}
try
{
managers(term);
}
catch(...){}
UniSetObject::sigterm(signo); UniSetObject::sigterm(signo);
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
......
...@@ -134,16 +134,27 @@ stCountOfQueueFull(0) ...@@ -134,16 +134,27 @@ stCountOfQueueFull(0)
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
UniSetObject::~UniSetObject() UniSetObject::~UniSetObject()
{ {
deactivate(); try
{
deactivate();
}
catch(...){}
tmr->terminate(); try
{
tmr->terminate();
}
catch(...){}
if( thr ) if( thr )
{ {
thr->stop(); try
{
if( thr->isRunning() ) thr->stop();
thr->join(); if( thr->isRunning() )
thr->join();
}
catch(...){}
delete thr; delete thr;
} }
...@@ -621,7 +632,8 @@ bool UniSetObject::deactivate() ...@@ -621,7 +632,8 @@ bool UniSetObject::deactivate()
} }
setActive(false); // завершаем поток обработки сообщений setActive(false); // завершаем поток обработки сообщений
tmr->stop(); if( tmr )
tmr->stop();
// Очищаем очередь // Очищаем очередь
{ // lock { // lock
...@@ -756,8 +768,8 @@ void UniSetObject::work() ...@@ -756,8 +768,8 @@ void UniSetObject::work()
if( thr ) if( thr )
msgpid = thr->getTID(); msgpid = thr->getTID();
while( isActive() ) while( isActive() )
callback(); callback();
uinfo << myname << ": thread processing messages stopped..." << endl; uinfo << myname << ": thread processing messages stopped..." << endl;
} }
...@@ -816,10 +828,17 @@ void UniSetObject::processingMessage( UniSetTypes::VoidMessage *msg ) ...@@ -816,10 +828,17 @@ void UniSetObject::processingMessage( UniSetTypes::VoidMessage *msg )
<< " mesg: " << fe.errmsg() << endl; << " mesg: " << fe.errmsg() << endl;
} }
} }
catch(...) catch( const std::exception& ex )
{
ucrit << myname << "(processingMessage): " << ex.what() << endl;
}
/*
catch( ... )
{ {
ucrit << myname << "(processingMessage): catch..." << endl; std::exception_ptr p = std::current_exception();
ucrit <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
} }
*/
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
......
...@@ -719,7 +719,7 @@ IOController_i::ShortIOInfo IOController::getChangedTime( UniSetTypes::ObjectId ...@@ -719,7 +719,7 @@ IOController_i::ShortIOInfo IOController::getChangedTime( UniSetTypes::ObjectId
err << myname << "(getChangedTime): вход(выход) с именем " err << myname << "(getChangedTime): вход(выход) с именем "
<< conf->oind->getNameById(sid) << " не найден"; << conf->oind->getNameById(sid) << " не найден";
uinfo << err.str() << endl; uinfo << err.str() << endl;
throw IOController_i::NameNotFound(err.str().c_str()); throw IOController_i::NameNotFound(err.str().c_str());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -161,6 +161,6 @@ void NCRestorer::init_depends_signals( IONotifyController* ic ) ...@@ -161,6 +161,6 @@ void NCRestorer::init_depends_signals( IONotifyController* ic )
IOController::ChangeSignal s = ic->signal_change_value(it->second.d_si.id); IOController::ChangeSignal s = ic->signal_change_value(it->second.d_si.id);
s.connect( sigc::mem_fun( &it->second, &IOController::USensorInfo::checkDepend) ); s.connect( sigc::mem_fun( &it->second, &IOController::USensorInfo::checkDepend) );
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -504,16 +504,16 @@ void Configuration::initParameters() ...@@ -504,16 +504,16 @@ void Configuration::initParameters()
if( confDir.empty() ) if( confDir.empty() )
confDir = getRootDir(); confDir = getRootDir();
} }
} }
// Heartbeat init... // Heartbeat init...
xmlNode* cnode = getNode("HeartBeatTime"); xmlNode* cnode = getNode("HeartBeatTime");
if( cnode ) if( cnode )
{ {
UniXML_iterator hit(cnode); UniXML_iterator hit(cnode);
heartbeat_msec = hit.getIntProp("msec"); heartbeat_msec = hit.getIntProp("msec");
if( heartbeat_msec <= 0 ) if( heartbeat_msec <= 0 )
heartbeat_msec = 5000; heartbeat_msec = 5000;
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -701,7 +701,10 @@ xmlNode* Configuration::initDebug( DebugStream& deb, const string& _debname ) ...@@ -701,7 +701,10 @@ xmlNode* Configuration::initDebug( DebugStream& deb, const string& _debname )
else else
{ {
if( !getProp(dnode,"name").empty() ) if( !getProp(dnode,"name").empty() )
{
debname = getProp(dnode,"name"); debname = getProp(dnode,"name");
deb.setLogName(debname);
}
} }
string no_deb("--"+debname+"-no-debug"); string no_deb("--"+debname+"-no-debug");
...@@ -978,6 +981,7 @@ UniversalIO::IOType Configuration::getIOType( const std::string& name ) ...@@ -978,6 +981,7 @@ UniversalIO::IOType Configuration::getIOType( const std::string& name )
void uniset_init( int argc, const char* const* argv, const std::string& xmlfile ) void uniset_init( int argc, const char* const* argv, const std::string& xmlfile )
{ {
string confile = UniSetTypes::getArgParam( "--confile", argc, argv, xmlfile ); string confile = UniSetTypes::getArgParam( "--confile", argc, argv, xmlfile );
ulog.setLogName("ulog");
UniSetTypes::conf = new Configuration(argc, argv, confile); UniSetTypes::conf = new Configuration(argc, argv, confile);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
noinst_LTLIBRARIES = libVarious.la noinst_LTLIBRARIES = libVarious.la
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS) libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS) libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libVarious_la_SOURCES = DebugStream.cc Debug.cc UniXML.cc MessageType.cc Configuration.cc \ libVarious_la_SOURCES = UniXML.cc MessageType.cc Configuration.cc \
Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc
local-clean: local-clean:
rm -rf *iSK.cc rm -rf *iSK.cc
#include <time.h> #include <time.h>
#include "Debug.h" #include "Debug.h"
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "LogAgregator.h"
using namespace std; using namespace std;
using namespace UniSetTypes; using namespace UniSetTypes;
std::ostringstream ss;
std::ostringstream ss1;
void check_log_signal( const string& s )
{
ss << s;
}
void check_alog_signal( const string& s )
{
ss1 << s;
}
int main( int argc, const char **argv ) int main( int argc, const char **argv )
{ {
DebugStream tlog; DebugStream tlog;
tlog.signal_stream_event().connect(&check_log_signal);
tlog.addLevel(Debug::ANY); tlog.addLevel(Debug::ANY);
tlog[Debug::INFO] << ": [info] ..." << endl; tlog[Debug::INFO] << ": [info] ..." << endl;
...@@ -20,5 +37,41 @@ int main( int argc, const char **argv ) ...@@ -20,5 +37,41 @@ int main( int argc, const char **argv )
if( tlog.is_level1() ) if( tlog.is_level1() )
tlog.level1() << ": is level1..." << endl; tlog.level1() << ": is level1..." << endl;
cout << "===== Test 1 =====" << endl;
cout << ss.str();
cout << "==================" << endl;
DebugStream log1;
log1.setLogName("log1");
DebugStream log2;
log2.setLogName("log2");
LogAgregator la;
la.signal_stream_event().connect(&check_alog_signal);
la.add(log1);
la.add(log2);
log1 << "log1: test message..." << endl;
log2 << "log2: test message..." << endl;
la << "la: test message.." << endl;
cout << "===== Test 2 =====" << endl;
cout << ss1.str();
cout << "==================" << endl;
DebugStream* l = la.getLog("log1");
if( l != &log1 )
cout << "**** TEST FAILED: LogAgregator::getLog() " << endl;
cout << "===== Test 3 =====" << endl;
tlog.level(Debug::ANY);
tlog.logFile("tlog.log");
tlog << "TEST TEXT" << endl;
tlog.logFile("tlog.log",true);
return 0; return 0;
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "Mutex.h" #include "Mutex.h"
#include "ThreadCreator.h" #include "ThreadCreator.h"
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "modbus/TCPCheck.h" #include "TCPCheck.h"
using namespace std; using namespace std;
using namespace UniSetTypes; using namespace UniSetTypes;
......
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