Commit 212cf7fb authored by Pavel Vainerman's avatar Pavel Vainerman

initial commit "1.0-pre"

parent 801f3c9a
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2007/06/17 21:30:49 $
*/
// --------------------------------------------------------------------------
#include <sstream>
#include "DBInterface.h"
using namespace std;
// -----------------------------------------------------------------------------------------
DBInterface::DBInterface():
result(0),
lastQ(""),
queryok(false)
{
mysql = new MYSQL();
}
DBInterface::~DBInterface()
{
close();
delete mysql;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::connect( const string host, const string user, const string pswd, const string dbname)
{
mysql_init(mysql);
// mysql_options(mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
mysql_options(mysql,MYSQL_OPT_COMPRESS,0);
if (!mysql_real_connect(mysql,host.c_str(), user.c_str(),pswd.c_str(),dbname.c_str(),0,NULL,0))
{
cout << error() << endl;
mysql_close(mysql);
return false;
}
return true;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::close()
{
mysql_close(mysql);
return true;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::insert(const string q)
{
if( !mysql )
return false;
if( mysql_query(mysql,q.c_str()) )
{
queryok=false;
return false;
}
queryok=true;
return true;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::query(const string q)
{
if( !mysql )
return false;
if( mysql_query(mysql,q.c_str()) )
{
queryok=false;
return false;
}
lastQ = q;
result = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
if( numRows()==0 )
{
queryok=false;
return false;
}
queryok=true;
return true;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::nextRecord()
{
if( !mysql || !result || !queryok )
return false;
if( Row == mysql_fetch_row(result) )
return true;
return false;
}
// -----------------------------------------------------------------------------------------
const string DBInterface::error()
{
return mysql_error(mysql);
}
// -----------------------------------------------------------------------------------------
const string DBInterface::lastQuery()
{
return lastQ;
}
// -----------------------------------------------------------------------------------------
void DBInterface::freeResult()
{
if( !mysql || !result || !queryok )
return;
queryok = false;
mysql_free_result( result );
}
// -----------------------------------------------------------------------------------------
int DBInterface::insert_id()
{
if( !mysql )
return 0;
return mysql_insert_id(mysql);
}
// -----------------------------------------------------------------------------------------
unsigned int DBInterface::numCols()
{
if( result )
return mysql_num_fields(result);
return 0;
}
// -----------------------------------------------------------------------------------------
unsigned int DBInterface::numRows()
{
if( result )
return mysql_num_rows(result);
return 0;
}
// -----------------------------------------------------------------------------------------
const MYSQL_ROW DBInterface::getRow()
{
return Row;
}
// -----------------------------------------------------------------------------------------
const char* DBInterface::gethostinfo()
{
return mysql_get_host_info(mysql);
}
// -----------------------------------------------------------------------------------------
/*
bool DBInterface::createDB(const string dbname)
{
if(!mysql)
return false;
if( mysql_create_db(mysql, dbname.c_str()) )
return true;
return false;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::dropDB(const string dbname)
{
if( mysql_drop_db(mysql, dbname.c_str()))
return true;
return false;
}
*/
// -----------------------------------------------------------------------------------------
MYSQL_RES* DBInterface::listFields(const string table, const string wild )
{
if( !mysql || !result )
return false;
MYSQL_RES *res = mysql_list_fields(mysql, table.c_str(),wild.c_str());
unsigned int cols = mysql_num_fields(result); // numCols();
MYSQL_ROW row=mysql_fetch_row(res);
// MYSQL_FIELD *field = mysql_fetch_fields(res);
// cout << field << " | ";
for( unsigned int i = 0; i<cols; i++)
{
cout << row[i] << " | ";
}
return res; // mysql_list_fields(mysql, table,wild);
}
// -----------------------------------------------------------------------------------------
bool DBInterface::moveToRow(int ind)
{
if(!mysql || !result)
return false;
mysql_data_seek(result, ind);
return true;
}
// -----------------------------------------------------------------------------------------
bool DBInterface::ping()
{
if(!mysql)
return false;
// внимание mysql_ping возвращает 0
// если всё хорошо.... (поэтому мы инвертируем)
return !mysql_ping(mysql);
}
// -----------------------------------------------------------------------------------------
bool DBInterface::isConnection()
{
return ping(); //!mysql;
}
// -----------------------------------------------------------------------------------------
string DBInterface::addslashes(const string& str)
{
ostringstream tmp;
for( unsigned int i=0; i<str.size(); i++ )
{
// if( !strcmp(str[i],'\'') )
if( str[i] == '\'' )
tmp << "\\";
tmp << str[i];
}
return tmp.str();
}
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2005/08/28 20:55:53 $
* \version $Id: DBInterface.h,v 1.1 2005/08/28 20:55:53 vpashka Exp $
*/
//----------------------------------------------------------------------------
#ifndef DBInterface_H_
#define DBInterface_H_
// ---------------------------------------------------------------------------
#include <string>
#include <iostream>
//#warning Для использования mysql_create нужен define USE_OLD_FUNCTIONS
//#define USE_OLD_FUNCTIONS
#include <mysql/mysql.h>
using std::string;
// ----------------------------------------------------------------------------
class DBInterface
{
public:
DBInterface();
~DBInterface();
// bool createDB(const string dbname);
// bool dropDB(const string dbname);
MYSQL_RES * listFields(const string table, const string wild );
bool connect( const string host, const string user, const string pswd,
const string dbname);
bool close();
bool query(const string q);
const string lastQuery();
bool insert(const string q);
string addslashes(const string& str);
/*!
проверка связи с БД.
в случае отсутсвия попытка восстановить...
*/
bool ping();
/*! связь с БД установлена (была) */
bool isConnection();
bool nextRecord();
void freeResult();
unsigned int numCols();
unsigned int numRows();
bool moveToRow(int ind);
int insert_id();
const MYSQL_ROW getRow();
const string error();
MYSQL_ROW Row;
// *******************
const char* gethostinfo();
protected:
private:
MYSQL_RES *result;
MYSQL *mysql;
string lastQ;
bool queryok; // успешность текущего запроса
};
// ----------------------------------------------------------------------------------
#endif
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2005/08/28 20:55:53 $
* \version $Id: DBServer_MySQL.h,v 1.1 2005/08/28 20:55:53 vpashka Exp $
*/
// --------------------------------------------------------------------------
#ifndef DBServer_MySQL_H_
#define DBServer_MySQL_H_
// --------------------------------------------------------------------------
#include <map>
#include "UniSetTypes.h"
#include "DBInterface.h"
#include "DBServer.h"
//------------------------------------------------------------------------------------------
/*!
\page page_DBServer_MySQL (DBServer_MySQL) Реализация сервиса ведения БД на основе MySQL
- \ref sec_DBS_Comm
- \ref sec_DBS_Conf
- \ref sec_DBS_Tables
\section sec_DBS_Comm Общее описание работы DBServer_MySQL
Сервис предназначен для работы с БД MySQL. В его задачи входит
сохранение всех событий происходищих в системе в БД. К этим
событиям относятся изменение состояния датчиков, различные логи
работы процессов и т.п.
К моменту запуска, подразумевается, что неободимые таблицы уже
созданы, все необходимые настройки mysql сделаны.
\par
При работе с БД, сервис в основном пишет в БД. Обработка накопленных данных
ведётся уже другими программами (web-интерфейс).
\par
Для повышения надежности DBServer переодически ( DBServer_MySQL::PingTimer ) проверяет наличие связи с сервером БД.
В случае если связь пропала (или не была установлена при старте) DBServer пытается вновь переодически ( DBServer::ReconnectTimer )
произвести соединение. При этом все запросы которые поступают для запии в БД, пишутся в лог-файл.
\warning При каждой попытке восстановить соединение DBServer заново читает конф. файл. Поэтому он может подхватить
новые настройки.
\todo Может не сохранять текст, если задан код... (для экономии в БД)
\section sec_DBS_Conf Настройка DBServer
Объект DBServer берёт настройки из конфигурационного файла из секции \b<LocalDBServer>.
Возможно задать следующие параметры:
- \b dbname - название БД
- \b dbnode - узел БД
- \b dbuser - пользователь
- \b dbpass - пароль для доступа к БД
- \b pingTime - период проверки связи с сервером MySQL
- \b reconnectTime - время повторной попытки соединения с БД
\section sec_DBS_Tables Таблицы MySQL
К основным таблицам относятся следующие:
\code
DROP TABLE IF EXISTS ObjectsMap;
CREATE TABLE ObjectsMap (
name varchar(80) NOT NULL default '',
rep_name varchar(80) default NULL,
id int(4) NOT NULL default '0',
msg int(1) default 0,
PRIMARY KEY (id),
KEY rep_name (rep_name),
KEY msg (msg)
) TYPE=MyISAM;
DROP TABLE IF EXISTS AnalogSensors;
CREATE TABLE AnalogSensors (
num int(11) NOT NULL auto_increment,
node int(3) default NULL,
id int(4) default NULL,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(3) unsigned default '0',
value int(6) default NULL,
PRIMARY KEY (num),
KEY date (date,time,time_usec),
KEY node (node,id)
) TYPE=MyISAM;
--
-- Table structure for table `DigitalSensors`
--
DROP TABLE IF EXISTS DigitalSensors;
CREATE TABLE DigitalSensors (
num int(11) NOT NULL auto_increment,
node int(3) default NULL,
id int(4) default NULL,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(3) unsigned default '0',
state char(1) default NULL,
confirm time NOT NULL default '00:00:00',
PRIMARY KEY (num),
KEY date (date,time,time_usec),
KEY node (node,id),
KEY confirm(confirm)
) TYPE=MyISAM;
DROP TABLE IF EXISTS SensorsThreshold;
CREATE TABLE SensorsThreshold (
sid int(11) NOT NULL default '0',
alarm int(8) NOT NULL default '0',
warning int(8) NOT NULL default '0'
) TYPE=MyISAM;
\endcode
*/
class DBServer_MySQL:
public DBServer
{
public:
DBServer_MySQL( UniSetTypes::ObjectId id );
DBServer_MySQL();
~DBServer_MySQL();
protected:
typedef std::map<int, std::string> DBTableMap;
virtual void initDB(DBInterface *db){};
virtual void initDBTableMap(DBTableMap& tblMap){};
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
virtual void timerInfo( UniSetTypes::TimerMessage* tm );
virtual void sysCommand( UniSetTypes::SystemMessage* sm );
// Функции обработки пришедших сообщений
virtual void parse( UniSetTypes::SensorMessage* sm );
virtual void parse( UniSetTypes::DBMessage* dbmsg );
virtual void parse( UniSetTypes::InfoMessage* imsg );
virtual void parse( UniSetTypes::AlarmMessage* amsg );
virtual void parse( UniSetTypes::ConfirmMessage* cmsg );
bool writeToBase( const string& query );
virtual void init_dbserver();
void createTables( DBInterface* db );
inline const char* tblName(int key)
{
return tblMap[key].c_str();
}
enum Timers
{
PingTimer, /*!< таймер на переодическую проверку соединения с сервером БД */
ReconnectTimer /*!< таймер на повторную попытку соединения с сервером БД (или восстановления связи) */
};
DBInterface *db;
int PingTime;
int ReconnectTime;
bool connect_ok; /*! признак наличия соеднинения с сервером БД */
bool activate;
private:
DBTableMap tblMap;
};
//------------------------------------------------------------------------------------------
#endif
############################################################################
# This file is part of the UniSet library #
############################################################################
UMYSQL_VER=@LIBVER@
lib_LTLIBRARIES = libUniSet-mysql.la
libUniSet_mysql_la_LDFLAGS = -version-info $(UMYSQL_VER)
libUniSet_mysql_la_SOURCES = DBInterface.cc DBServer_MySQL.cc
libUniSet_mysql_la_LIBADD = $(top_builddir)/lib/libUniSet.la -lmysqlclient
libUniSet_mysql_la_LDFLAGS = -version-info @LIBVER@
bin_PROGRAMS = uniset-mysql-dbserver
uniset_mysql_dbserver_LDADD = libUniSet-mysql.la $(top_builddir)/lib/libUniSet.la
uniset_mysql_dbserver_SOURCES = main.cc
include $(top_builddir)/conf/setting.mk
# install
devel_include_HEADERS = *.h
devel_includedir = $(includedir)/@PACKAGE@/mysql
#!/bin/sh
ln -s -f /usr/bin/uniset-stop.sh stop.sh
ln -s -f ../../conf/test.xml test.xml
-- MySQL dump 9.10
--
-- Host: localhost Database: TESTBASE
-- ------------------------------------------------------
-- Server version 4.0.18-log
-- Создание пользователя для dbadmin-а
GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,LOCK TABLES,CREATE,DROP ON TESTBASE.* TO dbadmin@localhost IDENTIFIED BY 'dbadmin';
-- Создание пользователя для просмотра
GRANT SELECT ON TESTBASE.* TO dbreader@"%" IDENTIFIED BY 'dbreader';
--
-- Table structure for table `AnalogSensors`
--
DROP TABLE IF EXISTS AnalogSensors;
CREATE TABLE AnalogSensors (
num int(11) NOT NULL auto_increment,
node int(3) default NULL,
id int(4) default NULL,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(3) unsigned default '0',
value int(6) default NULL,
PRIMARY KEY (num),
KEY date (date,time,time_usec),
KEY node (node,id)
) TYPE=MyISAM;
--
-- Table structure for table `DigitalSensors`
--
DROP TABLE IF EXISTS DigitalSensors;
CREATE TABLE DigitalSensors (
num int(11) NOT NULL auto_increment,
node int(3) default NULL,
id int(4) default NULL,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(3) unsigned default '0',
state char(1) default NULL,
confirm time NOT NULL default '00:00:00',
PRIMARY KEY (num),
KEY date (date,time,time_usec),
KEY node (node,id),
KEY confirm(confirm)
) TYPE=MyISAM;
--
-- Table structure for table `EmergencyLog`
--
DROP TABLE IF EXISTS EmergencyLog;
CREATE TABLE EmergencyLog (
num int(11) NOT NULL auto_increment,
eid int(3) default NULL,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(3) unsigned default '0',
PRIMARY KEY (num),
KEY eid (eid,date,time,time_usec)
) TYPE=MyISAM;
--
-- Dumping data for table `EmergencyLog`
--
--
-- Table structure for table `EmergencyRecords`
--
DROP TABLE IF EXISTS EmergencyRecords;
CREATE TABLE EmergencyRecords (
num int(11) NOT NULL auto_increment,
enum int(11) default '-1',
sid int(4) default NULL,
time time NOT NULL default '00:00:00',
time_usec int(3) unsigned default '0',
value int(6) default NULL,
PRIMARY KEY (num),
KEY enum (enum),
KEY sid (sid,time,time_usec)
) TYPE=MyISAM;
--
-- Dumping data for table `EmergencyRecords`
--
--
-- Table structure for table `ObjectsMap`
--
DROP TABLE IF EXISTS ObjectsMap;
CREATE TABLE ObjectsMap (
name varchar(80) NOT NULL default '',
rep_name varchar(80) default NULL,
id int(4) NOT NULL default '0',
msg int(1) default 0,
PRIMARY KEY (id),
KEY rep_name (rep_name),
KEY msg (msg)
) TYPE=MyISAM;
--
-- Table structure for table `RSChannel`
--
DROP TABLE IF EXISTS RSChannel;
CREATE TABLE RSChannel (
num int(11) NOT NULL auto_increment,
node int(3) default NULL,
channel int(2) default NULL,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(8) unsigned default '0',
query int(3) default NULL,
errquery int(3) default NULL,
notaskquery int(3) default NULL,
PRIMARY KEY (num),
KEY node (node,channel),
KEY time (time,date,time_usec)
) TYPE=MyISAM;
DROP TABLE IF EXISTS Network;
CREATE TABLE Network(
num int(11) NOT NULL auto_increment,
date date NOT NULL default '0000-00-00',
time time NOT NULL default '00:00:00',
time_usec int(8) unsigned default 0,
master int(3) default NULL,
slave int(3) default NULL,
connection int(2) default NULL,
PRIMARY KEY (num),
KEY (master, slave, connection),
KEY (time, date,time_usec)
) TYPE=MyISAM;
--
-- Table structure for table `SensorsThreshold`
--
DROP TABLE IF EXISTS SensorsThreshold;
CREATE TABLE SensorsThreshold (
sid int(11) NOT NULL default '0',
alarm int(8) NOT NULL default '0',
warning int(8) NOT NULL default '0'
) TYPE=MyISAM;
DELETE FROM DigitalSensors WHERE date<кTE_SUB(NOW(),INTERVAL 10 DAY);
DELETE FROM AnalogSensors WHERE date<кTE_SUB(NOW(),INTERVAL 10 DAY);
DELETE FROM Messages WHERE date<кTE_SUB(NOW(),INTERVAL 10 DAY);
DELETE FROM RSChannel WHERE date<кTE_SUB(NOW(),INTERVAL 10 DAY);
DELETE FROM Network WHERE date<кTE_SUB(NOW(),INTERVAL 10 DAY);
#include "Configuration.h"
#include "DBServer_MySQL.h"
#include "ObjectsActivator.h"
#include "Debug.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static void short_usage()
{
cout << "Usage: uniset-mysql-dbserver [--name ObjectId] [--confile configure.xml]\n";
}
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
try
{
if( argc > 1 && !strcmp(argv[1],"--help") )
{
short_usage();
return 0;
}
uniset_init(argc,argv,"configure.xml");
ObjectId ID = conf->getDBServer();
// определяем ID объекта
string name = conf->getArgParam("--name");
if( !name.empty())
{
if( ID != UniSetTypes::DefaultObjectId )
{
unideb[Debug::WARN] << "(DBServer::main): переопределяем ID заданнй в "
<< conf->getConfFileName() << endl;
}
ID = conf->oind->getIdByName(conf->getServicesSection()+"/"+name);
if( ID == UniSetTypes::DefaultObjectId )
{
cerr << "(DBServer::main): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getServicesSection() << endl;
return 1;
}
}
else if( ID == UniSetTypes::DefaultObjectId )
{
cerr << "(DBServer::main): Не удалось определить ИДЕНТИФИКАТОР сервера" << endl;
short_usage();
return 1;
}
DBServer_MySQL dbs(ID);
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(&dbs));
act.run(false);
}
catch(Exception& ex)
{
cerr << "(DBServer::main): " << ex << endl;
}
catch(...)
{
cerr << "(DBServer::main): catch ..." << endl;
}
return 0;
}
#!/bin/sh
ulimit -Sc 1000000
uniset-start.sh -f ./uniset-mysql-dbserver --confile test.xml --name DBServer --unideb-add-levels info,crit,warn,level9,system
#!/bin/sh
ln -s -f /usr/bin/uniset-stop.sh stop.sh
ln -s -f ../../conf/test.xml test.xml
#!/bin/sh
ln -s -f /usr/bin/uniset-stop.sh stop.sh
ln -s -f ../../conf/test.xml test.xml
......@@ -40,7 +40,6 @@ int main( int argc, const char **argv )
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
act.run(false);
return 0;
}
catch( Exception& ex )
{
......@@ -51,6 +50,6 @@ int main( int argc, const char **argv )
cout << "(main): Неизвестное исключение!!!!"<< endl;
}
return 1;
return 0;
}
// ------------------------------------------------------------------------------------------
#!/bin/sh
ln -s -f /usr/bin/uniset-stop.sh stop.sh
ln -s -f ../../conf/test.xml test.xml
<?xml version='1.0' encoding="utf-8" ?>
<?xml version='1.0' encoding="koi8-r" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'
xmlns:date="http://exslt.org/dates-and-times">
<xsl:import href="ctl-cpp-common.xsl"/>
<xsl:output method="text" indent="yes" encoding="utf-8"/>
<xsl:output method="text" indent="yes" encoding="koi8-r"/>
<xsl:variable name="CLASSNAME">
<xsl:call-template name="settings"><xsl:with-param name="varname" select="'class-name'"/></xsl:call-template>
......@@ -14,9 +14,7 @@
<xsl:variable name="OID">
<xsl:call-template name="settings"><xsl:with-param name="varname" select="'ID'"/></xsl:call-template>
</xsl:variable>
<xsl:variable name="TESTMODE">
<xsl:call-template name="settings"><xsl:with-param name="varname" select="'testmode'"/></xsl:call-template>
</xsl:variable>
<!-- Генерирование main для UniSet_FSM -->
<xsl:template match="/">
......
......@@ -4,23 +4,23 @@
из которых складывается библиотека, и которые используются во многих
местах данной документации. Здесь приводятся определения этих терминов.
- \ref sec_Concept_Object
- \ref sec_Concept_ObjectTypes
- \ref sec_Concept_Message
- \ref sec_Concept_ObjectId
- \ref sec_Concept_Repository
- \ref sec_Concept_Sensor
- \ref sec_Concept_Process
- \ref sec_Cnpt_Object
- \ref sec_Cnpt_ObjectTypes
- \ref sec_Cnpt_Message
- \ref sec_Cnpt_ObjectId
- \ref sec_Cnpt_Repository
- \ref sec_Cnpt_Sensor
- \ref sec_Cnpt_Process
\section sec_Concept_Object Объект
\section sec_Cnpt_Object Объект
В разных местах описаний, в зависимости от контекста,
под "объектом" подразумевается либо объект класса так или иначе наследующегося
от базового класса библиотеки UniSetObject, либо
некий концептуальный программный объект способный
получать и обрабатывать сообщения.
\section sec_Concept_ObjectTypes Основные типы объектов
\section sec_Cnpt_ObjectTypes Основные типы объектов
В библиотеке произведено условное деление на следующие типы объектов:
- (простые) объекты - наследуются от класса UniSetObject
- контроллеры - являются наследниками класса IOController
......@@ -28,7 +28,7 @@
- узлы - в строгом смысле, не являются объектами,
но обладают уникальным идентификатором.
\section sec_Concept_Message Сообщения
\section sec_Cnpt_Message Сообщения
Вся система взаимодейтсвия между объектами в основном
построена на использовании сообщений (передаваемых
путём удаленного вызова специальных функций,
......@@ -45,17 +45,17 @@ UniSetTypes::Message::TheLastFieldOfTypeOfMessage.
enum MyMessageTypes
{
myBegin = UniSetTypes::Message::TheLastFieldOfTypeOfMessage,
myMessageType1,
myMessageType2,
myMessageType3,
myMessgeType1,
myMessgeType2,
myMessgeType3,
...
};
\endcode
\section sec_Concept_ObjectId Идентификатор объекта
\section sec_Cnpt_ObjectId Идентификатор объекта
Каждый объект, которому необходимо взаимодействовать с другими объектами
(в том числе датчиками см. \ref sec_Concept_Sensor) должен обладать уникальным
(в том числе датчиками см. \ref sec_Cnpt_Sensor) должен обладать уникальным
идентификатором. В качестве идентификатора выступает любое число типа \b UniSetTypes::ObjectId.
Зарезервированным числом является UniSetTypes::DefaultObjectId.
Минимальное требование - это уникальность в рамках одного узла.
......@@ -110,9 +110,9 @@ UniSetTypes::Message::TheLastFieldOfTypeOfMessage.
будет присвоен идентификатор (просто по порядку). См. \ref UniSetTypes::ObjectIndex_XML
\note Следует иметь ввиду, что автоматическое присвоение идентификаторов,
\b зависит \b от \b положения описания объекта в конфигурацинном файле.
\b зависит \b от \b положения описания объекта в конфигурацинном фале.
Поэтому если вставить новый объект в любой секции, то все идентификаторы после него,
станут недействительными (сместятся на единицу). Т.е. необходимо отслеживать,
станут недействительными (сместяться на единицу). Т.е. необходимо отслеживать,
что конфигурационные файлы на всех узлах собвпадают между собой.
\note Из-за не надёжности это способ не рекомендуется к использованию.
......@@ -170,9 +170,9 @@ UniSetTypes::Message::TheLastFieldOfTypeOfMessage.
не сложными скриптами).
\section sec_Concept_Repository Репозиторий объектов
\section sec_Cnpt_Repository Репозиторий объектов
\section sec_Concept_Sensor Датчик
\section sec_Cnpt_Sensor Датчик
Датчик - это одно из базовых понятий при построении систем на основе libuniset.
Датчик - это информационная единица. Практически любая информация
(о событиях, о состоянии того или иного процесса, объекта, сообщение оператору и т.п.)
......@@ -195,7 +195,7 @@ UniSetTypes::Message::TheLastFieldOfTypeOfMessage.
на передачу цифровой информации (не текстовой).
Например CAN, ModbusRTU, ModbusTCP и т.п.
\section sec_Concept_Process Процесс
\section sec_Cnpt_Process Процесс
Под процессом в документации чаще всего подразумевается системный
процесс (запущенная программа) выполняющий те или иные функции управления
и обменивающийся для этого с другими процессами сообщениями или
......
......@@ -9,8 +9,10 @@ uniset-start.sh -f ./uniset-iocontrol --smemory-id SharedMemory \
--io-polltime 100 \
--io-s-filter-field io \
--io-s-filter-value 1 \
--io-numcards 2 \
--iodev1 /dev/null \
--iodev2 /dev/null \
--io-test-lamp Input1_S \
--io-heartbeat-id AI_AS \
--io-sm-ready-test-sid Input1_S \
--unideb-add-levels any --dlog-add-levels any
--unideb-add-levels info,crit,warn,level9,system
......@@ -7,35 +7,12 @@ using namespace UniSetTypes;
using namespace UniSetExtensions;
// -------------------------------------------------------------------------
PassiveLProcessor::PassiveLProcessor( std::string lfile, UniSetTypes::ObjectId objId,
UniSetTypes::ObjectId shmID, SharedMemory* ic, const std::string& prefix ):
UniSetTypes::ObjectId shmID, SharedMemory* ic ):
UniSetObject_LT(objId),
shm(0)
{
logname = myname;
shm = new SMInterface(shmID,&(UniSetObject_LT::ui),objId,ic);
build(lfile);
// ********** HEARTBEAT *************
string heart = conf->getArgParam("--" + prefix + "-heartbeat-id",""); // it.getProp("heartbeat_id"));
if( !heart.empty() )
{
sidHeartBeat = conf->getSensorID(heart);
if( sidHeartBeat == DefaultObjectId )
{
ostringstream err;
err << myname << ": ID not found ('HeartBeat') for " << heart;
dlog[Debug::CRIT] << myname << "(init): " << err.str() << endl;
throw SystemError(err.str());
}
int heartbeatTime = conf->getArgPInt("--" + prefix + "-heartbeat-time",conf->getHeartBeatTime());
if( heartbeatTime )
ptHeartBeat.setTiming(heartbeatTime);
else
ptHeartBeat.setTiming(UniSetTimer::WaitUpTime);
maxHeartBeat = conf->getArgPInt("--" + prefix + "-heartbeat-max","10", 10);
}
}
PassiveLProcessor::~PassiveLProcessor()
......@@ -81,7 +58,7 @@ void PassiveLProcessor::askSensors( UniversalIO::UIOCommand cmd )
try
{
for( EXTList::iterator it=extInputs.begin(); it!=extInputs.end(); ++it )
shm->askSensor(it->sid,cmd);
UniSetObject::ui.askState(it->sid,cmd);
}
catch( Exception& ex )
{
......@@ -111,14 +88,13 @@ void PassiveLProcessor::sysCommand( UniSetTypes::SystemMessage *sm )
{
case SystemMessage::StartUp:
{
if( !shm->waitSMready(smReadyTimeout) )
if( !shm->waitSMready(10000) )
{
dlog[Debug::CRIT] << myname << "(ERR): SM not ready. Terminated... " << endl;
cerr << "(ERR): SM not ready. Terminated... " << endl;
raise(SIGTERM);
return;
}
UniSetTypes::uniset_mutex_lock l(mutex_start, 10000);
askSensors(UniversalIO::UIONotify);
askTimer(tidStep,LProcessor::sleepTime);
break;
......@@ -169,25 +145,6 @@ void PassiveLProcessor::sysCommand( UniSetTypes::SystemMessage *sm )
}
}
// -------------------------------------------------------------------------
bool PassiveLProcessor::activateObject()
{
// блокирование обработки Starsp
// пока не пройдёт инициализация датчиков
// см. sysCommand()
{
UniSetTypes::uniset_mutex_lock l(mutex_start, 5000);
UniSetObject_LT::activateObject();
initIterators();
}
return true;
}
// ------------------------------------------------------------------------------------------
void PassiveLProcessor::initIterators()
{
shm->initAIterator(aitHeartBeat);
}
// -------------------------------------------------------------------------
void PassiveLProcessor::setOuts()
{
// выcтавляем выходы
......@@ -198,25 +155,25 @@ void PassiveLProcessor::setOuts()
switch(it->iotype)
{
case UniversalIO::DigitalInput:
shm->saveLocalState(it->sid,it->lnk->from->getOut(),it->iotype);
UniSetObject::ui.saveState(it->sid,it->lnk->from->getOut(),it->iotype);
break;
case UniversalIO::DigitalOutput:
shm->setState(it->sid,it->lnk->from->getOut());
UniSetObject::ui.setState(it->sid,it->lnk->from->getOut());
break;
default:
dlog[Debug::CRIT] << myname << "(setOuts): неподдерживаемый тип iotype=" << it->iotype << endl;
cerr << "(LProcessor::setOuts): неподдерживаемый тип iotype=" << it->iotype << endl;
break;
}
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << myname << "(setOuts): " << ex << endl;
cerr << "(LProcessor::setOuts): " << ex << endl;
}
catch(...)
{
dlog[Debug::CRIT] << myname << "(setOuts): catch...\n";
cerr << "(LProcessor::setOuts): catch...\n";
}
}
}
......@@ -230,25 +187,25 @@ void PassiveLProcessor::sigterm( int signo )
switch(it->iotype)
{
case UniversalIO::DigitalInput:
shm->saveLocalState(it->sid,false,it->iotype);
UniSetObject::ui.saveState(it->sid,false,it->iotype);
break;
case UniversalIO::DigitalOutput:
shm->setState(it->sid,false);
UniSetObject::ui.setState(it->sid,false);
break;
default:
dlog[Debug::CRIT] << myname << "(sigterm): неподдерживаемый тип iotype=" << it->iotype << endl;
cerr << "(LProcessor::sigterm): неподдерживаемый тип iotype=" << it->iotype << endl;
break;
}
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << myname << "(sigterm): " << ex << endl;
cerr << "(LProcessor::sigterm): " << ex << endl;
}
catch(...)
{
dlog[Debug::CRIT] << myname << "(sigterm): catch...\n";
cerr << "(LProcessor::sigterm): catch...\n";
}
}
}
......@@ -286,7 +243,7 @@ void PassiveLProcessor::processingMessage( UniSetTypes::VoidMessage* msg )
}
catch(Exception& ex)
{
dlog[Debug::CRIT] << myname << "(processingMessage): " << ex << endl;
cout << myname << "(processingMessage): " << ex << endl;
}
}
// -----------------------------------------------------------------------------
bin_PROGRAMS = @PACKAGE@-mbtcpmaster
UMBTCP_VER=@LIBVER@
lib_LTLIBRARIES = libUniSetMBTCPMaster.la
libUniSetMBTCPMaster_la_LDFLAGS = -version-info $(UMBTCP_VER)
libUniSetMBTCPMaster_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS)
libUniSetMBTCPMaster_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_SOURCES = MBTCPMaster.cc
@PACKAGE@_mbtcpmaster_SOURCES = main.cc
@PACKAGE@_mbtcpmaster_LDADD = libUniSetMBTCPMaster.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS)
@PACKAGE@_mbtcpmaster_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
# install
devel_include_HEADERS = *.h
devel_includedir = $(pkgincludedir)/extensions
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libUniSetMBTCPMaster.pc
all-local:
ln -sf ../MBTCPMaster/$(devel_include_HEADERS) ../include
#!/bin/sh
ln -s -f ../../Utilities/scripts/uniset-start.sh
ln -s -f ../../Utilities/scripts/uniset-stop.sh stop.sh
ln -s -f ../../Utilities/scripts/uniset-functions.sh
ln -s -f ../../conf/test.xml test.xml
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libUniSetMBTCPMaster
Description: Support library for UniSetModbusTCPMaster
Requires: libUniSetExtensions libUniSetSharedMemory
Version: @VERSION@
Libs: -L${libdir} -lUniSetMBTCPMaster
Cflags: -I${includedir}/uniset
#include <sstream>
#include "MBTCPMaster.h"
#include "Configuration.h"
#include "Debug.h"
#include "ObjectsActivator.h"
#include "Extensions.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: autodetect" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--mbtcp-logfile filename - logfilename. Default: mbtcpmaster.log" << endl;
cout << endl;
MBTCPMaster::help_print(argc, argv);
return 0;
}
try
{
string confile=UniSetTypes::getArgParam("--confile",argc, argv, "configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--mbtcp-logfile"));
if( logfilename.empty() )
logfilename = "mbtcpmaster.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
MBTCPMaster* mb = MBTCPMaster::init_mbmaster(argc,argv,shmID);
if( !mb )
{
dlog[Debug::CRIT] << "(mbmaster): init MBTCPMaster failed." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(mb));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- MBTCP Exchange START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- MBTCP Exchange START -------------------------\n\n";
act.run(false);
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(mbtcpmaster): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(mbtcpmaster): catch ..." << std::endl;
}
return 0;
}
#!/bin/sh
uniset-start.sh -f ./uniset-mbtcpmaster \
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
--dlog-add-levels info,crit,warn,level4,level3 \
--mbtcp-filter-field mbtcp \
--mbtcp-filter-value 1 \
--mbtcp-gateway-iaddr 127.0.0.1 \
--mbtcp-gateway-port 2048 \
--mbtcp-recv-timeout 5000 \
--mbtcp-force-disconnect 1
#--mbtcp-filter-field mbtcp --mbtcp-filter-value 1
bin_PROGRAMS = @PACKAGE@-rtuexchange mtr-conv uniset-rtu188-state vtconv mtr-setup
URTU_VER=@LIBVER@
lib_LTLIBRARIES = libUniSetRTU.la
libUniSetRTU_la_LDFLAGS = -version-info $(URTU_VER)
libUniSetRTU_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS)
libUniSetRTU_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
libUniSetRTU_la_SOURCES = RTUStorage.cc RTUExchange.cc
@PACKAGE@_rtuexchange_SOURCES = rtuexchange.cc
@PACKAGE@_rtuexchange_LDADD = libUniSetRTU.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS)
@PACKAGE@_rtuexchange_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
mtr_conv_SOURCES = mtrconv.cc
mtr_conv_LDADD = $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
mtr_conv_CXXFLAGS = -I$(top_builddir)/extensions/include
mtr_setup_SOURCES = mtr-setup.cc
mtr_setup_LDADD = $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
mtr_setup_CXXFLAGS = -I$(top_builddir)/extensions/include
vtconv_SOURCES = vtconv.cc
vtconv_LDADD = $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
vtconv_CXXFLAGS = -I$(top_builddir)/extensions/include
uniset_rtu188_state_LDADD = libUniSetRTU.la $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
uniset_rtu188_state__CXXFLAGS = -I$(top_builddir)/extensions/include
uniset_rtu188_state_SOURCES = rtustate.cc
# install
devel_include_HEADERS = *.h
devel_includedir = $(pkgincludedir)/extensions
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libUniSetRTU.pc
all-local:
ln -sf ../RTUExchange/$(devel_include_HEADERS) ../include
// $Id: RTUExchange.h,v 1.2 2009/01/11 19:08:45 vpashka Exp $
// -----------------------------------------------------------------------------
#ifndef _RTUEXCHANGE_H_
#define _RTUEXCHANGE_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <map>
#include <vector>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "modbus/ModbusRTUMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "MTR.h"
#include "RTUStorage.h"
#include "IOBase.h"
#include "VTypes.h"
// -----------------------------------------------------------------------------
class RTUExchange:
public UniSetObject_LT
{
public:
RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
virtual ~RTUExchange();
/*! глобальная функция для инициализации объекта */
static RTUExchange* init_rtuexchange( int argc, const char* const* argv,
UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
static const int NoSafetyState=-1;
enum Timer
{
tmExchange
};
enum DeviceType
{
dtUnknown, /*!< неизвестный */
dtRTU, /*!< RTU (default) */
dtRTU188, /*!< RTU188 (Fastwell) */
dtMTR /*!< MTR (DEIF) */
};
static DeviceType getDeviceType( const std::string dtype );
friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
// -------------------------------------------------------------------------------
struct RTUDevice;
struct RegInfo;
struct RSProperty:
public IOBase
{
// only for RTU
short nbit; /*!< bit number) */
VTypes::VType vType; /*!< type of value */
short rnum; /*!< count of registers */
short nbyte; /*!< byte number (1-2) */
RSProperty():
nbit(-1),vType(VTypes::vtUnknown),
rnum(VTypes::wsize(VTypes::vtUnknown)),
nbyte(0),reg(0)
{}
RegInfo* reg;
};
friend std::ostream& operator<<( std::ostream& os, const RSProperty& p );
typedef std::list<RSProperty> PList;
static std::ostream& print_plist( std::ostream& os, PList& p );
typedef std::map<ModbusRTU::ModbusData,RegInfo*> RegMap;
struct RegInfo
{
RegInfo():
mbval(0),mbreg(0),mbfunc(ModbusRTU::fnUnknown),
mtrType(MTR::mtUnknown),
rtuJack(RTUStorage::nUnknown),rtuChan(0),
dev(0),offset(0),
q_num(0),q_count(1),mb_init(false),sm_init(false),
mb_init_mbreg(0)
{}
ModbusRTU::ModbusData mbval;
ModbusRTU::ModbusData mbreg; /*!< регистр */
ModbusRTU::SlaveFunctionCode mbfunc; /*!< функция для чтения/записи */
PList slst;
// only for MTR
MTR::MTRType mtrType; /*!< тип регистра (согласно спецификации на MTR) */
// only for RTU188
RTUStorage::RTUJack rtuJack;
int rtuChan;
RTUDevice* dev;
int offset;
// optimization
int q_num; /*! number in query */
int q_count; /*! count registers for query */
RegMap::iterator rit;
bool mb_init; /*!< init before use */
bool sm_init; /*!< SM init value */
ModbusRTU::ModbusData mb_init_mbreg; /*!< mb_init register */
};
friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
struct RTUDevice
{
RTUDevice():
speed(ComPort::ComSpeed38400),
respnond(false),
mbaddr(0),
dtype(dtUnknown),
resp_id(UniSetTypes::DefaultObjectId),
resp_state(false),
resp_invert(false),
resp_real(false),
resp_init(false),
rtu(0)
{
resp_trTimeout.change(false);
}
ComPort::Speed speed;
bool respnond;
ModbusRTU::ModbusAddr mbaddr; /*!< адрес устройства */
RegMap regmap;
DeviceType dtype; /*!< тип устройства */
UniSetTypes::ObjectId resp_id;
IOController::DIOStateList::iterator resp_dit;
PassiveTimer resp_ptTimeout;
Trigger resp_trTimeout;
bool resp_state;
bool resp_invert;
bool resp_real;
bool resp_init;
RTUStorage* rtu;
// return TRUE if state changed
bool checkRespond();
};
friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
typedef std::map<ModbusRTU::ModbusAddr,RTUDevice*> RTUDeviceMap;
friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
void printMap(RTUDeviceMap& d);
// ----------------------------------
protected:
RTUDeviceMap rmap;
ModbusRTUMaster* mb;
UniSetTypes::uniset_mutex mbMutex;
std::string devname;
ComPort::Speed defSpeed;
int recv_timeout;
bool use485F;
bool transmitCtl;
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void step();
void poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
void updateSM();
void updateRTU(RegMap::iterator& it);
void updateMTR(RegMap::iterator& it);
void updateRTU188(RegMap::iterator& it);
void updateRSProperty( RSProperty* p, bool write_only=false );
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd );
void initOutput();
void waitSMReady();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initMB( bool reopen=false );
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
void initDeviceList();
void initOffsetList();
RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
RegInfo* addReg( RegMap& rmap, ModbusRTU::ModbusData r, UniXML_iterator& it,
RTUDevice* dev, RegInfo* rcopy=0 );
RSProperty* addProp( PList& plist, RSProperty& p );
bool initMTRitem( UniXML_iterator& it, RegInfo* p );
bool initRTU188item( UniXML_iterator& it, RegInfo* p );
bool initRSProperty( RSProperty& p, UniXML_iterator& it );
bool initRegInfo( RegInfo* r, UniXML_iterator& it, RTUDevice* dev );
bool initRTUDevice( RTUDevice* d, UniXML_iterator& it );
bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
void rtuQueryOptimization( RTUDeviceMap& m );
void readConfiguration();
bool check_item( UniXML_iterator& it );
private:
RTUExchange();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool force_out; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID;
int polltime; /*!< переодичность обновления данных, [мсек] */
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::uniset_mutex pollMutex;
bool activated;
int activateTimeout;
bool rs_pre_clean;
bool noQueryOptimization;
bool allNotRespond;
Trigger trAllNotRespond;
PassiveTimer ptAllNotRespond;
};
// -----------------------------------------------------------------------------
#endif // _RS_EXCHANGE_H_
// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------
//! \version $Id: RTUStorage.h,v 1.1 2008/12/14 21:57:50 vpashka Exp $
// --------------------------------------------------------------------------
#ifndef _RTUSTORAGE_H_
#define _RTUSTORAGE_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include "modbus/ModbusTypes.h"
#include "UniSetTypes.h"
// -----------------------------------------------------------------------------
class ModbusRTUMaster;
// -----------------------------------------------------------------------------
class RTUStorage
{
public:
RTUStorage( ModbusRTU::ModbusAddr addr );
~RTUStorage();
void poll( ModbusRTUMaster* mb )
throw(ModbusRTU::mbException);
inline ModbusRTU::ModbusAddr getAddress(){ return addr; }
inline bool ping(){ return pingOK; }
inline void setPollADC( bool set ){ pollADC = set; }
inline void setPollDI( bool set ){ pollDI = set; }
inline void setPollDIO( bool set ){ pollDIO = set; }
inline void setPollUNIO( bool set ){ pollUNIO = set; }
enum RTUJack
{
nUnknown,
nJ1, // UNIO48 (FPGA0)
nJ2, // UNIO48 (FPGA1)
nJ5, // DIO 16
nX1, // АЦП (8)
nX2, // АЦП (8)
nX4, // DI (8)
nX5 // DI (8)
};
static RTUJack s2j( const std::string jack );
static std::string j2s( RTUJack j );
long getInt( RTUJack jack, unsigned short channel, UniversalIO::IOTypes t );
float getFloat( RTUJack jack, unsigned short channel, UniversalIO::IOTypes t );
bool getState( RTUJack jack, unsigned short channel, UniversalIO::IOTypes t );
static ModbusRTU::ModbusData getRegister( RTUJack jack, unsigned short channel, UniversalIO::IOTypes t );
// ДОДЕЛАТЬ: setState, setValue
void print();
friend std::ostream& operator<<(std::ostream& os, RTUStorage& m );
friend std::ostream& operator<<(std::ostream& os, RTUStorage* m );
protected:
ModbusRTU::ModbusAddr addr;
bool pingOK;
bool pollADC;
bool pollDI;
bool pollDIO;
bool pollUNIO;
float adc[8]; // АЦП
bool di[16]; // Порт 16DI
bool dio_do[16]; // Порт 16DIO DO
bool dio_di[16]; // Порт 16DIO DI
float dio_ai[16]; // Порт 16DIO AI
float dio_ao[16]; // Порт 16DIO AO
bool unio_do[48]; // Порт UNIO48 DO
bool unio_di[48]; // Порт UNIO48 DI
float unio_ai[24]; // Порт UNIO48 AI
float unio_ao[24]; // Порт UNIO48 AO
};
// --------------------------------------------------------------------------
#endif // _RTUSTORAGE_H_
// -----------------------------------------------------------------------------
#!/bin/sh
ln -s -f ../../Utilities/scripts/uniset-start.sh
ln -s -f ../../Utilities/scripts/uniset-stop.sh stop.sh
ln -s -f ../../Utilities/scripts/uniset-functions.sh
ln -s -f ../../conf/test.xml test.xml
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libUniSetRTU
Description: Support library for UniSetRTUExchange
Requires: libUniSetExtensions
Version: @VERSION@
Libs: -L${libdir} -lUniSetRTU
Cflags: -I${includedir}/uniset
// --------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include "UniSetTypes.h"
#include "MTR.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace MTR;
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: mtrconv TYPE[T1...T12,T16,T17] hex1 hex2\n");
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
unsigned short v1 = 0;
unsigned short v2 = 0;
const char* type="";
if( argc<2 )
{
print_help();
return 1;
}
type = argv[1];
v1 = UniSetTypes::uni_atoi(argv[2]);
if( argc>=4 )
{
v1 = UniSetTypes::uni_atoi(argv[3]);
v2 = UniSetTypes::uni_atoi(argv[2]);
}
if( !strcmp(type,"T1") )
cout << "(T1): v1=" << v1 << " --> (unsigned) " << v1 << endl;
else if( !strcmp(type,"T2") )
cout << "(T2): v1=" << v1 << " --> (signed) " << (signed short)v1 << endl;
else if( !strcmp(type,"T16") )
{
T16 t(v1);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
}
else if( !strcmp(type,"T17") )
{
T17 t(v1);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
}
else if( !strcmp(type,"T3") )
{
T3 t(v1,v2);
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << (long)t << endl;
}
else if( !strcmp(type,"T4") )
{
T4 t(v1);
cout << "(T4): v1=" << t.raw
<< " --> " << t.sval << endl;
}
else if( !strcmp(type,"T5") )
{
T5 t(v1,v2);
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t.raw.u2.val << " * 10^" << (int)t.raw.u2.exp
<< " ===> " << t.val << endl;
}
else if( !strcmp(type,"T6") )
{
T6 t(v1,v2);
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t.raw.u2.val << " * 10^" << (int)t.raw.u2.exp
<< " ===> " << t.val << endl;
}
else if( !strcmp(type,"T7") )
{
T7 t(v1,v2);
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
// << " --> " << T7.val << " * 10^-4"
<< " ===> " << t.val
<< " [" << ( t.raw.u2.ic == 0xFF ? "CAP" : "IND" ) << "|"
<< ( t.raw.u2.ie == 0xFF ? "EXP" : "IMP" ) << "]"
<< endl;
}
else if( !strcmp(type,"T8") )
{
T8 t(v1,v2);
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << setfill('0') << hex
<< setw(2) << t.hour() << ":" << setw(2) << t.min()
<< " " << setw(2) << t.day() << "/" << setw(2) << t.mon()
<< endl;
}
else if( !strcmp(type,"T9") )
{
T9 t(v1,v2);
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << setfill('0') << hex
<< setw(2) << t.hour() << ":" << setw(2) << t.min()
<< ":" << setw(2) << t.sec() << "." << setw(2) << t.ssec()
<< endl;
}
else if( !strcmp(type,"T10") )
{
T10 t(v1,v2);
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << setfill('0') << dec
<< setw(4) << t.year() << "/" << setw(2) << t.mon()
<< "/" << setw(2) << t.day()
<< endl;
}
else if( !strcmp(type,"F1") )
{
F1 f(v1,v2);
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f.raw.val << endl;
}
else
{
cout << " Unknown type: " << type << endl;
}
return 0;
}
// --------------------------------------------------------------------------
#include <sstream>
#include "ObjectsActivator.h"
#include "Extensions.h"
#include "RTUExchange.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, char** argv )
{
try
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: read from <SharedMemory>" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--rs-logfile filename - logfilename. Default: rtuexchange.log" << endl;
cout << endl;
RTUExchange::help_print(argc, argv);
return 0;
}
string confile=UniSetTypes::getArgParam("--confile", argc, argv, "configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--rs-logfile"));
if( logfilename.empty() )
logfilename = "rtuexchange.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
RTUExchange* rs = RTUExchange::init_rtuexchange(argc,argv,shmID);
if( !rs )
{
dlog[Debug::CRIT] << "(rtuexchange): init не прошёл..." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(rs));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- RTU Exchange START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- RTU Exchange START -------------------------\n\n";
act.run(false);
// msleep(500);
// rs->execute();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(rtuexchange): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(rtuexchange): catch ..." << std::endl;
}
return 0;
}
// --------------------------------------------------------------------------
#include <string>
#include <getopt.h>
#include "modbus/ModbusRTUMaster.h"
#include "RTUStorage.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "slave", required_argument, 0, 'q' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: rtustate -q addr\n");
printf("-h|--help - this message\n");
printf("[-q|--slave] addr - Slave address. Default: 0x01.\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("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusAddr slaveaddr = 0x01;
int tout = 2000;
DebugStream dlog;
int use485 = 0;
try
{
while( (opt = getopt_long(argc, argv, "hva:d:s:t:q:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'q':
slaveaddr = ModbusRTU::str2mbAddr(optarg);
break;
case 'v':
verb = 1;
break;
case 'y':
use485 = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev
<< " speed=" << speed
<< " timeout=" << tout << " msec "
<< endl;
}
ModbusRTUMaster mb(dev,use485);
if( verb )
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
mb.setTimeout(tout);
mb.setSpeed(speed);
mb.setLog(dlog);
RTUStorage rtu(slaveaddr);
rtu.poll(&mb);
cout << rtu << endl;
for( int i=0; i<24; i++ )
cout << "UNIO1 AI" << i << ": " << rtu.getFloat( RTUStorage::nJ1, i, UniversalIO::AnalogInput ) << endl;
for( int i=0; i<24; i++ )
cout << "UNIO1 DI" << i << ": " << rtu.getState( RTUStorage::nJ1, i, UniversalIO::DigitalInput ) << endl;
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(rtustate): " << ex << endl;
}
catch(SystemError& err)
{
cerr << "(rtustate): " << err << endl;
}
catch(Exception& ex)
{
cerr << "(rtustate): " << ex << endl;
}
catch(...)
{
cerr << "(rtustate): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
#!/bin/sh
uniset-start.sh -f ./uniset-rtuexchange --confile test.xml \
--smemory-id SharedMemory \
--rs-dev /dev/cbsideA0 \
--rs-name RTUExchange \
--rs-speed 38400 \
--rs-filter-field rs \
--rs-filter-value 1 \
--dlog-add-levels info,crit,warn,level4,level3 \
--rs-force 0 \
--rs-force-out 0 \
#,level3
# --rs-force 1 \
// --------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include "UniSetTypes.h"
#include "VTypes.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace VTypes;
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n");
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
VTypes::F2 f2;
f2.raw.val = 2.345;
cout << "Example(F2): float=" << f2.raw.val
<< " regs:"
<< " v[0]=" << f2.raw.v[0]
<< " v[1]=" << f2.raw.v[1]
<< endl;
VTypes::F4 f4;
f4.raw.val = 2.345123123;
cout << "Example(F4): float=" << f4.raw.val
<< " regs:"
<< " v[0]=" << f4.raw.v[0]
<< " v[1]=" << f4.raw.v[1]
<< " v[2]=" << f4.raw.v[2]
<< " v[3]=" << f4.raw.v[3]
<< endl;
cout << "-------------" << endl << endl;
VTypes::I2 i2;
i2.raw.val = -6553004;
cout << "Example(I2): int=" << i2.raw.val
<< " regs:"
<< " v[0]=" << i2.raw.v[0]
<< " v[1]=" << i2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
VTypes::U2 u2;
u2.raw.val = 655300400;
cout << "Example(U2): unsigned int=" << u2.raw.val
<< " regs:"
<< " v[0]=" << u2.raw.v[0]
<< " v[1]=" << u2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
// return 0;
unsigned short v[4];
memset(v,0,sizeof(v));
const char* type="";
if( argc<3 )
{
print_help();
return 1;
}
type = argv[1];
v[0] = UniSetTypes::uni_atoi(argv[2]);
if( argc>3 )
v[1] = UniSetTypes::uni_atoi(argv[3]);
if( argc>4 )
v[2] = UniSetTypes::uni_atoi(argv[4]);
if( argc>5 )
v[3] = UniSetTypes::uni_atoi(argv[5]);
if( !strcmp(type,"F2") )
{
VTypes::F2 f(v,sizeof(v));
cout << "(F2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"F4") )
{
VTypes::F4 f(v,sizeof(v));
cout << "(F4): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " v[2]=" << v[2]
<< " v[3]=" << v[3]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"I2") )
{
VTypes::I2 i(v,sizeof(v));
cout << "(I2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl;
}
else if( !strcmp(type,"U2") )
{
VTypes::U2 i(v,sizeof(v));
cout << "(U2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl;
}
else
{
cout << " Unknown type: " << type << endl;
}
return 0;
}
// --------------------------------------------------------------------------
/*! $Id$ */
//--------------------------------------------------------------------------------
#ifndef _SMVIEWER_H
#define _SMVIEWER_H
......
#!/bin/sh
ln -s -f /usr/bin/uniset-stop.sh stop.sh
ln -s -f ../../conf/test.xml test.xml
bin_PROGRAMS = @PACKAGE@-udpexchange @PACKAGE@-udpsender @PACKAGE@-udpreceiver
UUDP_VER=@LIBVER@
lib_LTLIBRARIES = libUniSetUDP.la
libUniSetUDP_la_LDFLAGS = -version-info $(UUDP_VER)
libUniSetUDP_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(COMCPP_LIBS)
libUniSetUDP_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libUniSetUDP_la_SOURCES = UDPPacket.cc UDPExchange.cc UDPSender.cc UDPNReceiver.cc UDPReceiver.cc
#UDPSender.cc
@PACKAGE@_udpexchange_SOURCES = udpexchange.cc
@PACKAGE@_udpexchange_LDADD = libUniSetUDP.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(COMCPP_LIBS)
@PACKAGE@_udpexchange_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
@PACKAGE@_udpsender_SOURCES = udpsender.cc
@PACKAGE@_udpsender_LDADD = libUniSetUDP.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(COMCPP_LIBS)
@PACKAGE@_udpsender_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
@PACKAGE@_udpreceiver_SOURCES = udpreceiver.cc
@PACKAGE@_udpreceiver_LDADD = libUniSetUDP.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(COMCPP_LIBS)
@PACKAGE@_udpreceiver_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
# install
devel_include_HEADERS = *.h
devel_includedir = $(pkgincludedir)/extensions
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libUniSetUDP.pc
all-local:
ln -sf ../UDPExchange/$(devel_include_HEADERS) ../include
#ifndef UDPExchange_H_
#define UDPExchange_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <vector>
#include <cc++/socket.h>
#include "UniSetObject_LT.h"
#include "Trigger.h"
#include "Mutex.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "ThreadCreator.h"
#include "UDPPacket.h"
#include "UDPNReceiver.h"
// -----------------------------------------------------------------------------
class UDPExchange:
public UniSetObject_LT
{
public:
UDPExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
virtual ~UDPExchange();
/*! глобальная функция для инициализации объекта */
static UDPExchange* init_udpexchange( int argc, char* argv[],
UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, char* argv[] );
struct UItem
{
UItem():
val(0)
{}
IOController_i::SensorInfo si;
IOController::AIOStateList::iterator ait;
IOController::DIOStateList::iterator dit;
UniSetTypes::uniset_spin_mutex val_lock;
UniSetUDP::UDPMessage::UDPDataList::iterator pack_it;
long val;
friend std::ostream& operator<<( std::ostream& os, UItem& p );
};
protected:
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void poll();
void recv();
void send();
void step();
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
void askSensors( UniversalIO::UIOCommand cmd );
void waitSMReady();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
void readConfiguration();
bool check_item( UniXML_iterator& it );
void buildReceiverList();
private:
UDPExchange();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
int polltime; /*!< переодичность обновления данных, [мсек] */
ost::UDPBroadcast* udp;
ost::IPV4Host host;
ost::tpport_t port;
std::string s_host;
UniSetTypes::uniset_mutex pollMutex;
Trigger trTimeout;
int recvTimeout;
int sendTimeout;
bool activated;
int activateTimeout;
UniSetUDP::UDPMessage mypack;
typedef std::vector<UItem> DMap;
DMap dlist;
int maxItem;
typedef std::list<UDPNReceiver*> ReceiverList;
ReceiverList rlist;
ThreadCreator<UDPExchange>* thr;
};
// -----------------------------------------------------------------------------
#endif // UDPExchange_H_
// -----------------------------------------------------------------------------
#include <sstream>
#include "Exceptions.h"
#include "Extensions.h"
#include "UDPNReceiver.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
UDPNReceiver::UDPNReceiver( ost::tpport_t p, ost::IPV4Host h, UniSetTypes::ObjectId shmId, IONotifyController* ic ):
shm(0),
ui(conf),
activate(false),
udp(0),
host(h),
port(p),
recvTimeout(5000),
conn(false)
{
{
ostringstream s;
s << host << ":" << port;
myname = s.str();
}
shm = new SMInterface(shmId,&ui,DefaultObjectId,ic);
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << "(UDPNReceiver): UDP set to " << host << ":" << port << endl;
try
{
udp = new ost::UDPDuplex(host,port);
}
catch( ost::SockException& e )
{
ostringstream s;
s << e.getString() << ": " << e.getSystemErrorString() << endl;
throw SystemError(s.str());
}
thr = new ThreadCreator<UDPNReceiver>(this, &UDPNReceiver::poll);
thr->start();
}
// -----------------------------------------------------------------------------
UDPNReceiver::~UDPNReceiver()
{
delete udp;
delete shm;
delete thr;
}
// -----------------------------------------------------------------------------
void UDPNReceiver::poll()
{
while( 1 )
{
if( !activate )
{
msleep(1000);
continue;
}
try
{
recv();
}
catch( ost::SockException& e )
{
cerr << e.getString() << ": " << e.getSystemErrorString() << endl;
}
catch( UniSetTypes::Exception& ex)
{
cerr << myname << "(step): " << ex << std::endl;
}
catch(...)
{
cerr << myname << "(step): catch ..." << std::endl;
}
}
cerr << "************* execute FINISH **********" << endl;
}
// -----------------------------------------------------------------------------
void UDPNReceiver::recv()
{
cout << myname << ": recv....(timeout=" << recvTimeout << ")" << endl;
// UniSetUDP::UDPHeader h;
// receive
if( udp->isInputReady(recvTimeout) )
{
/*
ssize_t ret = udp->UDPReceive::receive(&h,sizeof(h));
if( ret<(ssize_t)sizeof(h) )
{
cerr << myname << "(receive): ret=" << ret << " sizeof=" << sizeof(h) << endl;
return;
}
cout << myname << "(receive): header: " << h << endl;
if( h.dcount <=0 )
{
cout << " data=0" << endl;
return;
}
*/
UniSetUDP::UDPData d;
// ignore echo...
#if 0
if( h.nodeID == conf->getLocalNode() && h.procID == getId() )
{
for( int i=0; i<h.dcount;i++ )
{
ssize_t ret = udp->UDPReceive::receive(&d,sizeof(d));
if( ret < (ssize_t)sizeof(d) )
return;
}
return;
}
#endif
cout << "***** request: " << udp->UDPSocket::getIPV4Peer() << endl;
for( int i=0; i<100;i++ )
{
ssize_t ret = udp->UDPReceive::receive(&d,sizeof(d));
if( ret<(ssize_t)sizeof(d) )
{
cerr << myname << "(receive data " << i << "): ret=" << ret << " sizeof=" << sizeof(d) << endl;
break;
}
cout << myname << "(receive data " << i << "): " << d << endl;
}
}
// else
// {
// cout << "no InputReady.." << endl;
// }
}
// -----------------------------------------------------------------------------
#ifndef UDPNReceiver_H_
#define UDPNReceiver_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <vector>
#include <cc++/socket.h>
#include "Mutex.h"
#include "Trigger.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "ThreadCreator.h"
#include "UDPPacket.h"
// -----------------------------------------------------------------------------
class UDPNReceiver
{
public:
UDPNReceiver( ost::tpport_t port, ost::IPV4Host host, UniSetTypes::ObjectId shmID, IONotifyController* ic=0 );
virtual ~UDPNReceiver();
inline int getPort(){ return port; }
inline bool isConnetcion(){ return conn; }
inline void start(){ activate = true; }
inline void stop(){ activate = false; }
inline void setReceiveTimeout( int t ){ recvTimeout = t; }
inline std::string getName(){ return myname; }
protected:
SMInterface* shm;
UniversalInterface ui;
void poll();
void recv();
std::string myname;
private:
UDPNReceiver();
bool activate;
ost::UDPDuplex* udp;
ost::IPV4Host host;
ost::tpport_t port;
int recvTimeout;
bool conn;
ThreadCreator<UDPNReceiver>* thr;
};
// -----------------------------------------------------------------------------
#endif // UDPNReceiver_H_
// -----------------------------------------------------------------------------
#include "UDPPacket.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetUDP;
// -----------------------------------------------------------------------------
std::ostream& UniSetUDP::operator<<( std::ostream& os, UniSetUDP::UDPHeader& p )
{
return os << "nodeID=" << p.nodeID
<< " procID=" << p.procID
<< " dcount=" << p.dcount;
}
// -----------------------------------------------------------------------------
std::ostream& UniSetUDP::operator<<( std::ostream& os, UniSetUDP::UDPData& p )
{
return os << "id=" << p.id << " val=" << p.val;
}
// -----------------------------------------------------------------------------
std::ostream& UniSetUDP::operator<<( std::ostream& os, UniSetUDP::UDPMessage& p )
{
return os;
}
// -----------------------------------------------------------------------------
UDPMessage::UDPMessage()
{
}
// -----------------------------------------------------------------------------
void UDPMessage::addData( const UniSetUDP::UDPData& dat )
{
dlist.push_back(dat);
}
// -----------------------------------------------------------------------------
void UDPMessage::addData( long id, long val)
{
UDPData d(id,val);
addData(d);
}
// -----------------------------------------------------------------------------
// $Id: UDPPacket.h,v 1.1 2009/02/10 20:38:27 vpashka Exp $
// -----------------------------------------------------------------------------
#ifndef UDPPacket_H_
#define UDPPacket_H_
// -----------------------------------------------------------------------------
#include <list>
#include <ostream>
#include "UniSetTypes.h"
// -----------------------------------------------------------------------------
namespace UniSetUDP
{
struct UDPHeader
{
long nodeID;
long procID;
long dcount;
friend std::ostream& operator<<( std::ostream& os, UDPHeader& p );
}__attribute__((packed));
struct UDPData
{
UDPData():id(UniSetTypes::DefaultObjectId),val(0){}
UDPData(long id, long val):id(id),val(val){}
long id;
long val;
friend std::ostream& operator<<( std::ostream& os, UDPData& p );
}__attribute__((packed));
struct UDPMessage:
public UDPHeader
{
UDPMessage();
void addData( const UDPData& dat );
void addData( long id, long val );
inline int size(){ return dlist.size(); }
typedef std::list<UDPData> UDPDataList;
UDPDataList dlist;
friend std::ostream& operator<<( std::ostream& os, UDPMessage& p );
};
}
// -----------------------------------------------------------------------------
#endif // UDPPacket_H_
// -----------------------------------------------------------------------------
#ifndef UDPReceiver_H_
#define UDPReceiver_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <vector>
#include <cc++/socket.h>
#include "UniSetObject_LT.h"
#include "Trigger.h"
#include "Mutex.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "ThreadCreator.h"
#include "UDPPacket.h"
// -----------------------------------------------------------------------------
class UDPReceiver:
public UniSetObject_LT
{
public:
UDPReceiver( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
virtual ~UDPReceiver();
/*! глобальная функция для инициализации объекта */
static UDPReceiver* init_udpreceiver( int argc, char* argv[],
UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, char* argv[] );
protected:
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void poll();
void recv();
void step();
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
void askSensors( UniversalIO::UIOCommand cmd );
void waitSMReady();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initIterators();
private:
UDPReceiver();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
int polltime; /*!< переодичность обновления данных, [мсек] */
ost::UDPDuplex* udp;
ost::IPV4Host host;
ost::tpport_t port;
UniSetTypes::uniset_mutex pollMutex;
Trigger trTimeout;
int recvTimeout;
bool activated;
int activateTimeout;
ThreadCreator<UDPReceiver>* thr;
};
// -----------------------------------------------------------------------------
#endif // UDPReceiver_H_
// -----------------------------------------------------------------------------
#ifndef UDPSender_H_
#define UDPSender_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <vector>
#include <cc++/socket.h>
#include "UniSetObject_LT.h"
#include "Trigger.h"
#include "Mutex.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "ThreadCreator.h"
#include "UDPPacket.h"
// -----------------------------------------------------------------------------
class UDPSender:
public UniSetObject_LT
{
public:
UDPSender( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
virtual ~UDPSender();
/*! глобальная функция для инициализации объекта */
static UDPSender* init_udpsender( int argc, char* argv[],
UniSetTypes::ObjectId shmID, SharedMemory* ic=0 );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, char* argv[] );
struct UItem
{
UItem():
val(0)
{}
IOController_i::SensorInfo si;
IOController::AIOStateList::iterator ait;
IOController::DIOStateList::iterator dit;
UniSetTypes::uniset_spin_mutex val_lock;
UniSetUDP::UDPMessage::UDPDataList::iterator pack_it;
long val;
friend std::ostream& operator<<( std::ostream& os, UItem& p );
};
protected:
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void poll();
void recv();
void send();
void step();
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
void askSensors( UniversalIO::UIOCommand cmd );
void waitSMReady();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
void readConfiguration();
bool check_item( UniXML_iterator& it );
private:
UDPSender();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
int sendtime; /*!< переодичность посылки данных, [мсек] */
ost::UDPSocket* udp;
ost::IPV4Host host;
ost::tpport_t port;
UniSetTypes::uniset_mutex sendMutex;
Trigger trTimeout;
int sendTimeout;
bool activated;
int activateTimeout;
UniSetUDP::UDPMessage mypack;
typedef std::vector<UItem> DMap;
DMap dlist;
int maxItem;
ThreadCreator<UDPSender>* thr;
};
// -----------------------------------------------------------------------------
#endif // UDPSender_H_
// -----------------------------------------------------------------------------
#!/bin/sh
ln -s -f ../../Utilities/scripts/uniset-start.sh
ln -s -f ../../Utilities/scripts/uniset-stop.sh stop.sh
ln -s -f ../../Utilities/scripts/uniset-functions.sh
ln -s -f ../../conf/test.xml test.xml
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libUniSetUDP
Description: Support library for UniSetIOControl
Requires: libUniSetExtensions
Version: @VERSION@
Libs: -L${libdir} -lUniSetUDP
Cflags: -I${includedir}/uniset
#!/bin/sh
uniset-start.sh -f ./uniset-udpexchange --udp-name UDPExchange --udp-host 192.168.56.255 \
--udp-broadcast 1 --udp-polltime 1000 \
--confile test.xml \
--dlog-add-levels info,crit,warn
# --udp-filter-field udp --udp-filter-value 1 \
#!/bin/sh
uniset-start.sh -f ./uniset-udpexchange --udp-name UDPExchange2 --udp-host localhost --udp-port 2049 \
--confile test.xml \
--udp-filter-field udp --udp-filter-value 2 \
--udp-ip \
--dlog-add-levels info,crit,warn
#!/bin/sh
uniset-start.sh -f ./uniset-udpreceiver --udp-name UDPExchange \
--udp-host 192.168.56.255 --udp-port 3000 \
--confile test.xml \
--udp-filter-field udp --udp-filter-value 1 \
--dlog-add-levels info,crit,warn
#!/bin/sh
uniset-start.sh -f ./uniset-udpsender --udp-name UDPExchange \
--udp-host 192.168.56.255 --udp-port 2050 --udp-broadcast 1\
--udp-sendtime 2000 \
--confile test.xml \
--dlog-add-levels info,crit,warn
# --udp-filter-field udp --udp-filter-value 1 \
#include <sstream>
#include "ObjectsActivator.h"
#include "Extensions.h"
#include "UDPExchange.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, char** argv )
{
try
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: read from <SharedMemory>" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--udp-logfile filename - logfilename. Default: udpexchange.log" << endl;
cout << endl;
UDPExchange::help_print(argc,argv);
return 0;
}
string confile=UniSetTypes::getArgParam("--confile",argc,argv,"configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--udp-logfile"));
if( logfilename.empty() )
logfilename = "udpexchange.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
UDPExchange* rs = UDPExchange::init_udpexchange(argc,argv,shmID);
if( !rs )
{
dlog[Debug::CRIT] << "(udpexchange): init не прошёл..." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(rs));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- UDP Exchange START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- UDP Exchange START -------------------------\n\n";
act.run(false);
// msleep(500);
// rs->execute();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(udpexchange): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(udpexchange): catch ..." << std::endl;
}
return 0;
}
#include <sstream>
#include "ObjectsActivator.h"
#include "Extensions.h"
#include "UDPReceiver.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, char** argv )
{
try
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: read from <SharedMemory>" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--udp-logfile filename - logfilename. Default: udpexchange.log" << endl;
cout << endl;
UDPReceiver::help_print(argc,argv);
return 0;
}
string confile=UniSetTypes::getArgParam("--confile",argc,argv,"configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--udp-logfile"));
if( logfilename.empty() )
logfilename = "udpexchange.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
UDPReceiver* udp = UDPReceiver::init_udpreceiver(argc,argv,shmID);
if( !udp )
{
dlog[Debug::CRIT] << "(udpreceiver): init не прошёл..." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(udp));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- UDPRecevier START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- UDPReceiver START -------------------------\n\n";
act.run(false);
// msleep(500);
// rs->execute();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(udpexchange): " << ex << std::endl;
}
catch( ost::SockException& e )
{
ostringstream s;
s << e.getString() << ": " << e.getSystemErrorString();
dlog[Debug::CRIT] << s.str() << endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(udpexchange): catch ..." << std::endl;
}
return 0;
}
#include <sstream>
#include "ObjectsActivator.h"
#include "Extensions.h"
#include "UDPSender.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, char** argv )
{
try
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: read from <SharedMemory>" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--udp-logfile filename - logfilename. Default: udpexchange.log" << endl;
cout << endl;
UDPSender::help_print(argc,argv);
return 0;
}
string confile=UniSetTypes::getArgParam("--confile",argc,argv,"configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--udp-logfile"));
if( logfilename.empty() )
logfilename = "udpexchange.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
UDPSender* udp = UDPSender::init_udpsender(argc,argv,shmID);
if( !udp )
{
dlog[Debug::CRIT] << "(udpsender): init не прошёл..." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(udp));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- UDPSender START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- UDPSender START -------------------------\n\n";
act.run(false);
// msleep(500);
// rs->execute();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(udpsender): " << ex << std::endl;
}
catch( ost::SockException& e )
{
dlog[Debug::CRIT] << "(udpsender): " << e.getSystemErrorString() << endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(udpsender): catch ..." << std::endl;
}
return 0;
}
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2008/02/07 21:04:56 $
* \version $Id: CallBackTimer_template.h,v 1.6 2008/02/07 21:04:56 vpashka Exp $
*/
// --------------------------------------------------------------------------
# ifndef CallBackTimer_TEMPLATE_H_
# define CallBackTimer_TEMPLATE_H_
// --------------------------------------------------------------------------
#include <unistd.h>
#include <sstream>
#include "CallBackTimer.h"
// ------------------------------------------------------------------------------------------
template <class Caller> class CallBackTimer;
// ------------------------------------------------------------------------------------------
/*! Создание таймера
\param r - указатель на заказчика
*/
template <class Caller>
CallBackTimer<Caller>::CallBackTimer( Caller* r, Action a ):
cal(r),
act(a),
terminated(false)
{
thr = new ThreadCreator<CallBackTimer>(this, &CallBackTimer<Caller>::work);
}
// ------------------------------------------------------------------------------------------
template <class Caller>
CallBackTimer<Caller>::CallBackTimer():
cal(null),
terminated(false)
{
thr = new ThreadCreator<CallBackTimer>(this, &CallBackTimer<Caller>::work);
}
// ------------------------------------------------------------------------------------------
template <class Caller>
CallBackTimer<Caller>::~CallBackTimer()
{
terminate();
clearTimers();
delete thr;
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::work()
{
terminated = false;
while( !terminated )
{
usleep(UniSetTimer::MIN_QUANTITY_TIME_MKS);
for( typename TimersList::iterator li=lst.begin(); li!=lst.end(); ++li )
{
if( li->pt.checkTime() )
{
(cal->*act)( li->id );
li->pt.reset();
}
}
}
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::run()
{
if( !terminated )
terminate();
startTimers();
// PosixThread::start(static_cast<PosixThread*>(this));
thr->start();
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::terminate()
{
// timeAct = 0;
terminated = true;
usleep(1000);
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::add( int id, int timeMS )throw(UniSetTypes::LimitTimers)
{
if( lst.size() >= MAXCallBackTimer )
{
ostringstream err;
err << "CallBackTimers: превышено максимальное количество таймеров" << MAXCallBackTimer;
throw UniSetTypes::LimitTimers(err.str());
}
PassiveTimer pt(timeMS);
TimerInfo ti(id, pt);
lst.push_back(ti);
// lst[id] = ti;
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::remove( int id )
{
// STL - способ поиска
typename TimersList::iterator li= find_if(lst.begin(),lst.end(),FindId_eq(id));
if( li!=lst.end() )
lst.erase(li);
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::startTimers()
{
for( typename TimersList::iterator li=lst.begin(); li!=lst.end(); ++li)
{
li->pt.reset();
}
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::clearTimers()
{
lst.clear();
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::reset( int id )
{
typename TimersList::iterator li= find_if(lst.begin(),lst.end(),FindId_eq(id));
if( li!=lst.end() )
li->pt.reset();
}
// ------------------------------------------------------------------------------------------
template <class Caller>
void CallBackTimer<Caller>::setTiming( int id, int timeMS )
{
typename TimersList::iterator li= find_if(lst.begin(),lst.end(),FindId_eq(id));
if( li!=lst.end() )
li->pt.setTimer(timeMS);
}
// ------------------------------------------------------------------------------------------
template <class Caller>
int CallBackTimer<Caller>::getInterval( int id )
{
typename TimersList::iterator li= find_if(lst.begin(),lst.end(),FindId_eq(id));
if( li!=lst.end() )
return li->pt.getInterval();
return -1;
}
// ------------------------------------------------------------------------------------------
template <class Caller>
int CallBackTimer<Caller>::getCurrent( int id )
{
typename TimersList::iterator li= find_if(lst.begin(),lst.end(),FindId_eq(id));
if( li!=lst.end() )
return li->pt.getCurrent();
return -1;
}
// ------------------------------------------------------------------------------------------
# endif //CallBackTimer_H_
......@@ -18,47 +18,46 @@
*/
// --------------------------------------------------------------------------
/*! \file
* \brief Реализация RepositoryAgent
* \author Pavel Vainerman
* \date $Date: 2005/01/28 20:52:21 $
* \version $Id: RepositoryAgent.h,v 1.5 2005/01/28 20:52:21 vitlav Exp $
*/
// --------------------------------------------------------------------------
#ifndef ProxyManager_H_
#define ProxyManager_H_
#ifndef RepositoryAgent_H_
#define RepositoryAgent_H_
//---------------------------------------------------------------------------
#include <map>
#include "UniSetObject.h"
//----------------------------------------------------------------------------
class PassiveObject;
//----------------------------------------------------------------------------
/*! \class ProxyManager
* Менеджер пассивных объектов, который выступает вместо них во всех внешних связях....
#include "RepositoryAgent_i.hh"
#include "BaseProcess_i.hh"
#include "BaseProcess.h"
#include "UniSetTypes.h"
#include "ObjectIndex.h"
//----------------------------------------------------------------------------------------
/*! \class RepositoryAgent
*/
class ProxyManager:
public UniSetObject
class RepositoryAgent:
public POA_RepositoryAgent_i,
public BaseProcess
{
public:
ProxyManager( UniSetTypes::ObjectId id );
~ProxyManager();
void attachObject( PassiveObject* po, UniSetTypes::ObjectId id );
void detachObject( UniSetTypes::ObjectId id );
RepositoryAgent( ObjectId id, const UniSetTypes::ObjectInfo *pObjectsMap );
~RepositoryAgent();
UniversalInterface* uin;
protected:
ProxyManager();
virtual void processingMessage( UniSetTypes::VoidMessage* msg );
virtual void allMessage( UniSetTypes::VoidMessage* msg );
// virtual void registration(const char* name, ::CORBA::Object_ptr ref);
// virtual void unregistration(const char* name, ::CORBA::Object_ptr ref);
virtual CORBA::Object_ptr resolve(const char* name);
virtual CORBA::Object_ptr resolveid( UniSetTypes::ObjectId id);
virtual bool activateObject();
virtual bool disactivateObject();
virtual void execute();
protected:
RepositoryAgent();
ObjectIndex oind;
private:
typedef std::map<UniSetTypes::ObjectId, PassiveObject*> PObjectMap;
PObjectMap omap;
};
//----------------------------------------------------------------------------------------
#endif // ProxyManager
//----------------------------------------------------------------------------------------
#endif
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Vitaly Lipatov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*! \file
* \author Vitaly Lipatov
* \date $Date: 2007/01/02 22:30:48 $
* \version $Id: TextFileIndex.h,v 1.7 2007/01/02 22:30:48 vpashka Exp $
* \par
* Базовый класс получения строки по её индексу
*/
#include <string>
class TextFileIndex: public TextIndex
{
public:
virtual ~TextFileIndex(){}
// Получить строку по коду
virtual std::string getText(int id);
// При инициализации указывается название файла для считывания
TextFileIndex(std::string filename);
};
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2008/06/01 21:36:19 $
* \version $Id: TriggerAND_template.h,v 1.8 2008/06/01 21:36:19 vpashka Exp $
*/
// --------------------------------------------------------------------------
#include "TriggerAND.h"
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
TriggerAND<Caller,InputType>::TriggerAND(Caller* c, Action a):
cal(c),
act(a)
{
}
template<class Caller, typename InputType>
TriggerAND<Caller,InputType>::~TriggerAND()
{
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
bool TriggerAND<Caller,InputType>::commit(InputType num, bool state)
{
typename InputMap::iterator it=inputs.find(num);
if( it!=inputs.end() )
{
inputs[num] = state;
check();
return true;
}
return false;
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerAND<Caller,InputType>::add(InputType num, bool state)
{
inputs[num] = state;
check();
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerAND<Caller,InputType>::remove(InputType num)
{
typename InputMap::iterator it=inputs.find(num);
if( it!=inputs.end() )
inputs.erase(it);
check();
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
bool TriggerAND<Caller,InputType>::getState(InputType num)
{
typename InputMap::iterator it=inputs.find(num);
if( it!=inputs.end() )
return it->second;
return false; // throw NotFound
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerAND<Caller,InputType>::check()
{
bool old = out;
for( typename InputMap::iterator it=inputs.begin(); it!=inputs.end(); ++it )
{
if( !it->second )
{
// если хоть один вход "0" на выходе "0"
// и прекращаем дальнейший поиск
out = false;
if( old != out )
{
// try
// {
(cal->*act)(out);
// }
// catch(...){}
}
return;
}
}
out = true;
if( old != out )
{
// try
// {
(cal->*act)(out);
// }
// catch(...){}
}
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerAND<Caller,InputType>::update()
{
(cal->*act)(out);
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerAND<Caller,InputType>::reset()
{
out = false;
(cal->*act)(out);
}
//---------------------------------------------------------------------------
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2008/06/01 21:36:19 $
* \version $Id: TriggerOR_template.h,v 1.8 2008/06/01 21:36:19 vpashka Exp $
*/
// --------------------------------------------------------------------------
#include "TriggerOR.h"
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
TriggerOR<Caller,InputType>::TriggerOR(Caller* c, Action a):
cal(c),
act(a)
{
}
template<class Caller, typename InputType>
TriggerOR<Caller,InputType>::~TriggerOR()
{
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
bool TriggerOR<Caller,InputType>::commit(InputType num, bool state)
{
typename InputMap::iterator it=inputs.find(num);
if( it!=inputs.end() )
{
inputs[num] = state;
check();
return true;
}
return false;
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerOR<Caller,InputType>::add(InputType num, bool state)
{
inputs[num] = state;
check();
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerOR<Caller,InputType>::remove(InputType num)
{
typename InputMap::iterator it=inputs.find(num);
if( it!=inputs.end() )
inputs.erase(it);
check();
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
bool TriggerOR<Caller,InputType>::getState(InputType num)
{
typename InputMap::iterator it=inputs.find(num);
if( it!=inputs.end() )
return it->second;
return false; // throw NotFound
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerOR<Caller,InputType>::check()
{
bool old = out;
for( typename InputMap::iterator it=inputs.begin(); it!=inputs.end(); ++it )
{
if( it->second )
{
// если хоть один вход "1" на выходе "1"
// и прекращаем дальнейший поиск
out = true;
if( old != out )
{
// try
// {
(cal->*act)(out);
// }
// catch(...){}
}
return;
}
}
out = false;
if( old != out )
{
// try
// {
(cal->*act)(out);
// }
// catch(...){}
}
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerOR<Caller,InputType>::update()
{
(cal->*act)(out);
}
//---------------------------------------------------------------------------
template<class Caller, typename InputType>
void TriggerOR<Caller,InputType>::reset()
{
out = false;
(cal->*act)(out);
}
//---------------------------------------------------------------------------
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
* \date $Date: 2008/06/01 21:36:19 $
* \version $Id: TriggerOutput_template.h,v 1.4 2008/06/01 21:36:19 vpashka Exp $
*/
// --------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "TriggerOutput.h"
//---------------------------------------------------------------------------
template<class Caller, typename OutIdType, typename ValueType>
TriggerOutput<Caller,OutIdType,ValueType>::TriggerOutput( Caller* r, Action a):
cal(r),
act(a)
{
}
template <class Caller, typename OutIdType, typename ValueType>
TriggerOutput<Caller,OutIdType,ValueType>::~TriggerOutput()
{
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::add(OutIdType num, ValueType val)
{
outs[num] = val;
set(num,val);
try
{
(cal->*act)(num,val);
}
catch(...){}
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::remove(OutIdType num)
{
typename OutList::iterator it=outs.find(num);
if( it!=outs.end() )
outs.erase(it);
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
bool TriggerOutput<Caller,OutIdType,ValueType>::getState(OutIdType out)
{
typename OutList::iterator it=outs.find(out);
if( it!=outs.end() )
return it->second;
return false;
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::set(OutIdType out, ValueType val)
{
typename OutList::iterator it=outs.find(out);
if( it==outs.end() )
return;
// потом val
ValueType prev(it->second);
it->second = val;
if( prev != val )
{
check(out); // выставляем сперва все нули
try
{
(cal->*act)(it->first, it->second);
}
catch(...){}
}
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::check(OutIdType newout)
{
for( typename OutList::iterator it=outs.begin(); it!=outs.end(); ++it )
{
if( it->first != newout && it->second )
{
it->second = 0;
// try
// {
(cal->*act)(it->first, it->second);
// }
// catch(...){}
}
}
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::update()
{
for( typename OutList::iterator it=outs.begin(); it!=outs.end(); ++it )
(cal->*act)(it->first, it->second);
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::reset()
{
for( typename OutList::iterator it=outs.begin(); it!=outs.end(); ++it )
{
it->second = 0;
(cal->*act)(it->first, it->second);
}
}
//---------------------------------------------------------------------------
......@@ -5,4 +5,3 @@
noinst_LTLIBRARIES = libThreads.la
libThreads_la_SOURCES=PosixThread.cc
include $(top_builddir)/conf/setting.mk
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Vitaly Lipatov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*! \file
* \author Vitaly Lipatov
* \date $Date: 2005/01/28 21:14:18 $
* \par
* Базовый класс получения строки по её индексу
*/
#include "TextFileIndex.h"
#include <iostream.h>
// В конструкторе загружаем значения из файла
std::string TextFileIndex::TextFileIndex(string filename)
{
textmap[id] = str;
}
//
std::string TextIndex::getText(int id)
{
return textmap[id];
}
#!/bin/sh
ln -s -f /usr/bin/uniset-stop.sh stop.sh
ln -s -f ../conf/test.xml test.xml
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