|
From: <tho...@us...> - 2011-10-17 21:07:29
|
Revision: 453
http://openautomation.svn.sourceforge.net/openautomation/?rev=453&view=rev
Author: thomas_s
Date: 2011-10-17 21:07:20 +0000 (Mon, 17 Oct 2011)
Log Message:
-----------
- removed some 'using' from headers
- did some refactoring
- implemented clean shutdown with CTRL-C and SIGTERM
- use range-based for loop (just for fun)
- some preperations for unit-testing
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/cmake/Modules/FindxPL.cmake
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
xPLHAL/branches/thomas_s_dev/src/devicemanager.h
xPLHAL/branches/thomas_s_dev/src/globals.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/xhcp.cpp
xPLHAL/branches/thomas_s_dev/src/xhcp.h
xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp
xPLHAL/branches/thomas_s_dev/src/xhcpthread.h
xPLHAL/branches/thomas_s_dev/src/xplcache.cpp
xPLHAL/branches/thomas_s_dev/src/xplcache.h
xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp
xPLHAL/branches/thomas_s_dev/src/xplhandler.h
xPLHAL/branches/thomas_s_dev/src/xplmessagequeue.cpp
xPLHAL/branches/thomas_s_dev/src/xplmessagequeue.h
Added Paths:
-----------
xPLHAL/branches/thomas_s_dev/ChangeLog
xPLHAL/branches/thomas_s_dev/src/i_properties.h
xPLHAL/branches/thomas_s_dev/src/xpldevice.h
xPLHAL/branches/thomas_s_dev/src/xplmessage.h
xPLHAL/branches/thomas_s_dev/test/
xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/test/test_test.cpp
Modified: xPLHAL/branches/thomas_s_dev/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/CMakeLists.txt 2011-10-17 20:29:50 UTC (rev 452)
+++ xPLHAL/branches/thomas_s_dev/CMakeLists.txt 2011-10-17 21:07:20 UTC (rev 453)
@@ -37,7 +37,7 @@
#set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
-find_package(Boost 1.38 COMPONENTS thread system filesystem date_time regex )
+find_package(Boost 1.38 COMPONENTS thread system filesystem date_time regex unit_test_framework)
find_package(xPL REQUIRED)
set(LIBS ${LIBS} ${Boost_LIBRARIES} ${xPL_LIBRARIES} pthread)
@@ -65,4 +65,5 @@
endif(Boost_USE_STATIC_LIBS)
add_subdirectory(src)
+add_subdirectory(test)
Added: xPLHAL/branches/thomas_s_dev/ChangeLog
===================================================================
--- xPLHAL/branches/thomas_s_dev/ChangeLog (rev 0)
+++ xPLHAL/branches/thomas_s_dev/ChangeLog 2011-10-17 21:07:20 UTC (rev 453)
@@ -0,0 +1,8 @@
+
+2011-10-17:
+Experimentally using c++0x features available with gcc-4.6.
+To compile create clean 'build' directory and call from build-dir:
+"CXX=g++-4.6 cmake .."
+
+Boost-Test is not working yet.
+
Modified: xPLHAL/branches/thomas_s_dev/cmake/Modules/FindxPL.cmake
===================================================================
--- xPLHAL/branches/thomas_s_dev/cmake/Modules/FindxPL.cmake 2011-10-17 20:29:50 UTC (rev 452)
+++ xPLHAL/branches/thomas_s_dev/cmake/Modules/FindxPL.cmake 2011-10-17 21:07:20 UTC (rev 453)
@@ -3,11 +3,13 @@
find_path( xPL_INCLUDE_DIR
NAMES xPL.h
PATHS /usr/local/include
+ PATHS /home/thomas/projects/xPLLib
)
find_library( xPL_LIBRARY
NAMES libxPL.so
PATHS /usr/local/lib
+ PATHS /home/thomas/projects/xPLLib
)
set( xPL_FOUND TRUE )
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2011-10-17 20:29:50 UTC (rev 452)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2011-10-17 21:07:20 UTC (rev 453)
@@ -17,6 +17,8 @@
project(xPLHAL)
cmake_minimum_required(VERSION 2.6)
+#set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -std=c++0x")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp xhcp.cpp main.cpp)
add_executable(xPLHAL ${xPLHAL_SRCS})
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2011-10-17 20:29:50 UTC (rev 452)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2011-10-17 21:07:20 UTC (rev 453)
@@ -1,20 +1,20 @@
/*
- xPLHAL implementation in C++
- Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
+ xPLHAL implementation in C++
+ Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
- 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 3 of the License, or
- (at your option) any later version.
+ 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 3 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.
+ 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, see <http://www.gnu.org/licenses/>.
-*/
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
@@ -23,379 +23,370 @@
using namespace boost::algorithm;
#include "log.h"
-
#include "devicemanager.h"
+using namespace boost::posix_time;
+
void deviceManagerClass::add( const xPLDevice& device ) const
{
- writeLog( "deviceManagerClass::add("+device.VDI+")", logLevel::debug );
- if( contains( device.VDI ) )
- update( device );
- else
- {
- string newtag = "device." + device.VDI + ".";
- ptime expires = second_clock::local_time() + minutes( 2*device.Interval + 1 );
+ writeLog( "deviceManagerClass::add("+device.VDI+")", logLevel::debug );
+ if( contains( device.VDI ) ) {
+ update( device );
+ } else {
+ std::string newtag = "device." + device.VDI + ".";
+ ptime expires = second_clock::local_time() + minutes( 2*device.Interval + 1 );
- xPLCache->updateEntry(newtag + "vdi", device.VDI, false);
- xPLCache->updateEntry(newtag + "configdone", device.ConfigDone?"true":"false", false);
- xPLCache->updateEntry(newtag + "configmissing", device.ConfigMissing?"true":"false", false);
- xPLCache->updateEntry(newtag + "configsource", device.ConfigSource, false);
- xPLCache->updateEntry(newtag + "configtype", device.ConfigType?"true":"false", false);
- xPLCache->updateEntry(newtag + "waitingconfig", device.WaitingConfig?"true":"false", false);
- xPLCache->updateEntry(newtag + "current", device.Current?"true":"false", false);
- xPLCache->updateEntry(newtag + "configlistsent", device.ConfigListSent?"true":"false", false);
- xPLCache->updateEntry(newtag + "suspended", device.Suspended?"true":"false", false);
- xPLCache->updateEntry(newtag + "interval", lexical_cast<string>(device.Interval), false);
- xPLCache->updateEntry(newtag + "expires", timeConverter( expires ), false);
- }
+ xPLCache->updateEntry(newtag + "vdi", device.VDI, false);
+ xPLCache->updateEntry(newtag + "configdone", device.ConfigDone?"true":"false", false);
+ xPLCache->updateEntry(newtag + "configmissing", device.ConfigMissing?"true":"false", false);
+ xPLCache->updateEntry(newtag + "configsource", device.ConfigSource, false);
+ xPLCache->updateEntry(newtag + "configtype", device.ConfigType?"true":"false", false);
+ xPLCache->updateEntry(newtag + "waitingconfig", device.WaitingConfig?"true":"false", false);
+ xPLCache->updateEntry(newtag + "current", device.Current?"true":"false", false);
+ xPLCache->updateEntry(newtag + "configlistsent", device.ConfigListSent?"true":"false", false);
+ xPLCache->updateEntry(newtag + "suspended", device.Suspended?"true":"false", false);
+ xPLCache->updateEntry(newtag + "interval", lexical_cast<std::string>(device.Interval), false);
+ xPLCache->updateEntry(newtag + "expires", timeConverter( expires ), false);
+ }
}
-bool deviceManagerClass::remove( const string& deviceTag ) const
+bool deviceManagerClass::remove( const std::string& deviceTag ) const
{
- writeLog( "deviceManagerClass::remove("+deviceTag+")", logLevel::debug );
- if( contains( deviceTag ) )
- {
- vector<string> list = xPLCache->childNodes( "device." + deviceTag );
- for( vector<string>::const_iterator it = list.begin(); it != list.end(); it++ )
- xPLCache->deleteEntry( *it );
- return true;
- } else
- return false;
+ writeLog( "deviceManagerClass::remove("+deviceTag+")", logLevel::debug );
+ if( contains( deviceTag ) ) {
+ std::vector<std::string> list = xPLCache->childNodes( "device." + deviceTag );
+ //for( std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); it++ )
+ for( auto it : list )
+ xPLCache->deleteEntry( it );
+ return true;
+ } else {
+ return false;
+ }
}
-bool deviceManagerClass::removeConfig( const string& deviceTag ) const
+bool deviceManagerClass::removeConfig( const std::string& deviceTag ) const
{
- writeLog( "deviceManagerClass::remove("+deviceTag+")", logLevel::debug );
- if( containsConfig( deviceTag ) )
- {
- vector<string> list = xPLCache->childNodes( "config." + deviceTag );
- for( vector<string>::const_iterator it = list.begin(); it != list.end(); it++ )
- xPLCache->deleteEntry( *it );
- return true;
- } else
- return false;
+ writeLog( "deviceManagerClass::remove("+deviceTag+")", logLevel::debug );
+ if( containsConfig( deviceTag ) ) {
+ std::vector<std::string> list = xPLCache->childNodes( "config." + deviceTag );
+ //for( std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); it++ )
+ for (auto it : list)
+ xPLCache->deleteEntry( it );
+ return true;
+ } else {
+ return false;
+ }
}
-xPLDevice deviceManagerClass::getDevice( const string& deviceTag ) const
+xPLDevice deviceManagerClass::getDevice( const std::string& deviceTag ) const
{
- xPLDevice retval;
- if( contains( deviceTag ) )
- {
- retval.ConfigDone = xPLCache->objectValue( "device." + deviceTag + ".configdone" ) == "true";
- retval.ConfigMissing = xPLCache->objectValue( "device." + deviceTag + ".configmissing" ) == "true";
- retval.ConfigSource = xPLCache->objectValue( "device." + deviceTag + ".configsource" );
- retval.ConfigType = xPLCache->objectValue( "device." + deviceTag + ".configtype" ) == "true";
- retval.Current = xPLCache->objectValue( "device." + deviceTag + ".current" ) == "true";
- retval.Expires = timeConverter( xPLCache->objectValue( "device." + deviceTag + ".expires" ) );
- retval.Interval = atoi(xPLCache->objectValue( "device." + deviceTag + ".interval" ).c_str());
- retval.VDI = xPLCache->objectValue( "device." + deviceTag + ".vdi" );
- retval.WaitingConfig = xPLCache->objectValue( "device." + deviceTag + ".waitingconfig" ) == "true";
- retval.ConfigListSent = xPLCache->objectValue( "device." + deviceTag + ".configlistsent" ) == "true";
- retval.Suspended = xPLCache->objectValue( "device." + deviceTag + ".suspended" ) == "true";
- }
- return retval;
+ xPLDevice retval;
+ if( contains( deviceTag ) ) {
+ retval.ConfigDone = xPLCache->objectValue( "device." + deviceTag + ".configdone" ) == "true";
+ retval.ConfigMissing = xPLCache->objectValue( "device." + deviceTag + ".configmissing" ) == "true";
+ retval.ConfigSource = xPLCache->objectValue( "device." + deviceTag + ".configsource" );
+ retval.ConfigType = xPLCache->objectValue( "device." + deviceTag + ".configtype" ) == "true";
+ retval.Current = xPLCache->objectValue( "device." + deviceTag + ".current" ) == "true";
+ retval.Expires = timeConverter( xPLCache->objectValue( "device." + deviceTag + ".expires" ) );
+ retval.Interval = atoi(xPLCache->objectValue( "device." + deviceTag + ".interval" ).c_str());
+ retval.VDI = xPLCache->objectValue( "device." + deviceTag + ".vdi" );
+ retval.WaitingConfig = xPLCache->objectValue( "device." + deviceTag + ".waitingconfig" ) == "true";
+ retval.ConfigListSent = xPLCache->objectValue( "device." + deviceTag + ".configlistsent" ) == "true";
+ retval.Suspended = xPLCache->objectValue( "device." + deviceTag + ".suspended" ) == "true";
+ }
+ return retval;
}
-vector<string> deviceManagerClass::getAllDeviceNames() const
+std::vector<std::string> deviceManagerClass::getAllDeviceNames() const
{
- vector<string> retval;
- vector<string> nodes = xPLCache->childNodes( "device." );
- for( vector<string>::iterator it = nodes.begin(); it != nodes.end(); ++it )
- {
- if( ends_with( *it, ".vdi" ) )
- {
- retval.push_back( it->substr( 7, it->size() - 7 - 4 ) ); // leave "device." and ".vdi" away
- writeLog( "deviceManagerClass::getAllDeviceNames() = "+ it->substr( 7, it->size() - 7 - 4 ), logLevel::debug );
+ std::vector<std::string> retval;
+ std::vector<std::string> nodes = xPLCache->childNodes( "device." );
+// for( std::vector<std::string>::iterator it = nodes.begin(); it != nodes.end(); ++it )
+ for (auto node : nodes) {
+ if( ends_with( node, ".vdi" ) ) {
+ retval.push_back( node.substr( 7, node.size() - 7 - 4 ) ); // leave "device." and ".vdi" away
+ writeLog( "deviceManagerClass::getAllDeviceNames() = "+ node.substr( 7, node.size() - 7 - 4 ), logLevel::debug );
+ }
}
- }
- return retval;
+ return retval;
}
void deviceManagerClass::update( const xPLDevice& device ) const
{
- writeLog( "deviceManagerClass::update("+device.VDI+") - known: "+ (contains( device.VDI )?"true":"false"), logLevel::debug );
+ writeLog( "deviceManagerClass::update("+device.VDI+") - known: "+ (contains( device.VDI )?"true":"false"), logLevel::debug );
- if( contains( device.VDI ) )
- remove( device.VDI );
- writeLog( "deviceManagerClass::update("+device.VDI+") -> add", logLevel::debug );
- add( device );
+ if( contains( device.VDI ) ) {
+ remove( device.VDI );
+ }
+ writeLog( "deviceManagerClass::update("+device.VDI+") -> add", logLevel::debug );
+ add( device );
}
void deviceManagerClass::processConfigList( const xPL_MessagePtr message ) const
{
- string source = string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
- xPLDevice device = getDevice( source );
- writeLog( "deviceManagerClass::processConfigList("+source+") - found ["+device.VDI+"]", logLevel::debug );
- if( "" == device.VDI )
- { // A config list turned up that we haven't asked for...
- // create a new device...
- const char* intervalString = xPL_getMessageNamedValue( message, "interval" );
- int interval = intervalString ? atoi(intervalString) : 5; // default to 5 minutes
- ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
- device.VDI = source; // vendor / device / instance = unique id
- device.ConfigDone = false; // false = new waiting check, true = sent/not required
- device.ConfigMissing = false; // true = no config file, no response from device, false = have/waiting config
- device.ConfigSource = "objectcache"; // v-d.xml / v-d.cache.xml or empty
- device.ConfigType = true; // true = config. false = hbeat.
- device.WaitingConfig = false; // false = waiting check or not needed, true = manual intervention
- device.Current = false; // asked for current config
- device.ConfigListSent = true; // Have we asked this device for it's config?
- device.Suspended = false; // lost heartbeat
- device.Interval = interval; // current heartbeat interval
- device.Expires = expires; // time expires
- update( device );
- }
+ std::string source = std::string("")
+ + xPL_getSourceVendor ( message ) + "-"
+ + xPL_getSourceDeviceID ( message ) + "."
+ + xPL_getSourceInstanceID( message );
+ xPLDevice device = getDevice( source );
+ writeLog( "deviceManagerClass::processConfigList("+source+") - found ["+device.VDI+"]", logLevel::debug );
+ if( "" == device.VDI ) {
+ // A config list turned up that we haven't asked for...
+ // create a new device...
+ const char* intervalString = xPL_getMessageNamedValue( message, "interval" );
+ int interval = intervalString ? atoi(intervalString) : 5; // default to 5 minutes
+ ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
+ device.VDI = source; // vendor / device / instance = unique id
+ device.ConfigDone = false; // false = new waiting check, true = sent/not required
+ device.ConfigMissing = false; // true = no config file, no response from device, false = have/waiting config
+ device.ConfigSource = "objectcache"; // v-d.xml / v-d.cache.xml or empty
+ device.ConfigType = true; // true = config. false = hbeat.
+ device.WaitingConfig = false; // false = waiting check or not needed, true = manual intervention
+ device.Current = false; // asked for current config
+ device.ConfigListSent = true; // Have we asked this device for it's config?
+ device.Suspended = false; // lost heartbeat
+ device.Interval = interval; // current heartbeat interval
+ device.Expires = expires; // time expires
+ update( device );
+ }
- xPL_NameValueListPtr nvList = xPL_getMessageBody( message );
- xPL_NameValuePairPtr nvPair = NULL;
- int nvCount = xPL_getNamedValueCount(nvList);
- for( int nvIndex = 0; nvIndex < nvCount; nvIndex++ )
- {
- string newtag = "config." + source + ".options.";
- nvPair = xPL_getNamedValuePairAt( nvList, nvIndex );
- string value = nvPair->itemValue; to_lower( value );
- string key = nvPair->itemName ; to_lower( key );
- boost::regex re( "([a-z0-9]{1,16})\\[(\\d{1,3})\\]" );
- boost::smatch matches;
- if( boost::regex_match( value, matches, re) )
- {
- xPLCache->updateEntry( newtag + matches[1] , "" , false );
- xPLCache->updateEntry( newtag + matches[1] + ".type" , key , false );
- xPLCache->updateEntry( newtag + matches[1] + ".count", matches[2], false );
- } else {
- xPLCache->updateEntry( newtag + value , "" , false );
- xPLCache->updateEntry( newtag + value + ".type" , key , false );
- xPLCache->updateEntry( newtag + value + ".count", "" , false );
+ xPL_NameValueListPtr nvList = xPL_getMessageBody( message );
+ xPL_NameValuePairPtr nvPair = NULL;
+ int nvCount = xPL_getNamedValueCount(nvList);
+ for( int nvIndex = 0; nvIndex < nvCount; nvIndex++ ) {
+ std::string newtag = "config." + source + ".options.";
+ nvPair = xPL_getNamedValuePairAt( nvList, nvIndex );
+ std::string value = nvPair->itemValue; to_lower( value );
+ std::string key = nvPair->itemName ; to_lower( key );
+ boost::regex re( "([a-z0-9]{1,16})\\[(\\d{1,3})\\]" );
+ boost::smatch matches;
+ if( boost::regex_match( value, matches, re) ) {
+ xPLCache->updateEntry( newtag + matches[1] , "" , false );
+ xPLCache->updateEntry( newtag + matches[1] + ".type" , key , false );
+ xPLCache->updateEntry( newtag + matches[1] + ".count", matches[2], false );
+ } else {
+ xPLCache->updateEntry( newtag + value , "" , false );
+ xPLCache->updateEntry( newtag + value + ".type" , key , false );
+ xPLCache->updateEntry( newtag + value + ".count", "" , false );
+ }
}
- }
- // send the config response, but only if we have a config (e.g. from the use via XHCP)
- if( xPLCache->exists( "config." + source + ".current" ) )
- {
- xPLCache->updateEntry( "device." + source + ".configdone", "true", false );
- sendConfigResponse( source, false );
- } else {
- // try to get at least the current config
- xPLMessage::namedValueList command_request; command_request.push_back( make_pair( "command", "request" ) );
- xPL->sendMessage( xPL_MESSAGE_COMMAND,
- xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
- "config", "current", command_request );
- }
+ // send the config response, but only if we have a config (e.g. from the use via XHCP)
+ if( xPLCache->exists( "config." + source + ".current" ) ) {
+ xPLCache->updateEntry( "device." + source + ".configdone", "true", false );
+ sendConfigResponse( source, false );
+ } else {
+ // try to get at least the current config
+ xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
+ xPL->sendMessage( xPL_MESSAGE_COMMAND,
+ xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
+ "config", "current", command_request );
+ }
}
void deviceManagerClass::processConfigHeartBeat( const xPL_MessagePtr message ) const
{
- string source = string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
- xPLDevice device = getDevice( source );
- writeLog( "deviceManagerClass::processConfigHeartBeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
- if( "" == device.VDI )
- { // this handles a new application that identifies itself with a hbeat straight away.
- // it must either be storing it's config locally, can't be configured, or is configured somewhere else.
- const char* intervalString = xPL_getMessageNamedValue( message, "interval" );
- int interval = intervalString ? atoi(intervalString) : 5; // default to 5 minutes
- ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
- device.VDI = source; // vendor / device / instance = unique id
- device.ConfigDone = false; // false = new waiting check, true = sent/not required
- device.ConfigMissing = true; // true = no config file, no response from device, false = have/waiting config
- device.ConfigSource = "xplmessage"; // v-d.xml / v-d.cache.xml or empty
- device.ConfigType = true; // true = config. false = hbeat.
- device.WaitingConfig = true; // false = waiting check or not needed, true = manual intervention
- device.Current = false; // asked for current config
- device.ConfigListSent = false; // Have we asked this device for it's config?
- device.Suspended = false; // lost heartbeat
- device.Interval = interval; // current heartbeat interval
- device.Expires = expires; // time expires
- update( device );
- } else {
- xPLCache->updateEntry( "device." + source + ".expires", timeConverter( second_clock::local_time() + minutes( 2*device.Interval + 1 ) ), false );
- // FIXME - that line look like that in the VB code - but it seems really strange!
- xPLCache->updateEntry( "device." + source + ".expires.configdone", "objectcache", false );
- }
+ std::string source = std::string("")
+ + xPL_getSourceVendor ( message ) + "-"
+ + xPL_getSourceDeviceID ( message ) + "."
+ + xPL_getSourceInstanceID( message );
+ xPLDevice device = getDevice( source );
+ writeLog( "deviceManagerClass::processConfigHeartBeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
+ if( "" == device.VDI ) {
+ // this handles a new application that identifies itself with a hbeat straight away.
+ // it must either be storing it's config locally, can't be configured, or is configured somewhere else.
+ const char* intervalString = xPL_getMessageNamedValue( message, "interval" );
+ int interval = intervalString ? atoi(intervalString) : 5; // default to 5 minutes
+ ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
+ device.VDI = source; // vendor / device / instance = unique id
+ device.ConfigDone = false; // false = new waiting check, true = sent/not required
+ device.ConfigMissing = true; // true = no config file, no response from device, false = have/waiting config
+ device.ConfigSource = "xplmessage"; // v-d.xml / v-d.cache.xml or empty
+ device.ConfigType = true; // true = config. false = hbeat.
+ device.WaitingConfig = true; // false = waiting check or not needed, true = manual intervention
+ device.Current = false; // asked for current config
+ device.ConfigListSent = false; // Have we asked this device for it's config?
+ device.Suspended = false; // lost heartbeat
+ device.Interval = interval; // current heartbeat interval
+ device.Expires = expires; // time expires
+ update( device );
+ } else {
+ xPLCache->updateEntry( "device." + source + ".expires", timeConverter( second_clock::local_time() + minutes( 2*device.Interval + 1 ) ), false );
+ // FIXME - that line look like that in the VB code - but it seems really strange!
+ xPLCache->updateEntry( "device." + source + ".expires.configdone", "objectcache", false );
+ }
- // ask device for configuration (if haven't asked it before...)
- if( !device.ConfigListSent )
- {
- xPLMessage::namedValueList command_request; command_request.push_back( make_pair( "command", "request" ) );
- xPL->sendMessage( xPL_MESSAGE_COMMAND,
- xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
- "config", "list", command_request );
- xPLCache->updateEntry( "device." + source + ".configlistsend", "true", false );
- }
+ // ask device for configuration (if haven't asked it before...)
+ if( !device.ConfigListSent ) {
+ xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
+ xPL->sendMessage( xPL_MESSAGE_COMMAND,
+ xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
+ "config", "list", command_request );
+ xPLCache->updateEntry( "device." + source + ".configlistsend", "true", false );
+ }
}
void deviceManagerClass::processCurrentConfig( const xPL_MessagePtr message ) const
{
- string source = string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
- xPLDevice device = getDevice( source );
- writeLog( "deviceManagerClass::processCurrentConfig("+source+") - found ["+device.VDI+"]", logLevel::debug );
- if( "" == device.VDI )
- { // A current config turned up for a device that we don't know...
- // Processing the current config doesn't make sense as long as we don't know the config list
- // => just treat it like an heartbeat
- return processConfigHeartBeat( message );
- } else {
- xPLCache->updateEntry( "config." + source + ".expires", timeConverter( second_clock::local_time() + minutes( 2*device.Interval + 1 ) ), false );
- xPLCache->updateEntry( "config." + source + ".current", "true", false );
- }
+ std::string source = std::string("")
+ + xPL_getSourceVendor ( message ) + "-"
+ + xPL_getSourceDeviceID ( message ) + "."
+ + xPL_getSourceInstanceID( message );
+ xPLDevice device = getDevice( source );
+ writeLog( "deviceManagerClass::processCurrentConfig("+source+") - found ["+device.VDI+"]", logLevel::debug );
+ if( "" == device.VDI ) {
+ // A current config turned up for a device that we don't know...
+ // Processing the current config doesn't make sense as long as we don't know the config list
+ // => just treat it like an heartbeat
+ return processConfigHeartBeat( message );
+ } else {
+ xPLCache->updateEntry( "config." + source + ".expires", timeConverter( second_clock::local_time() + minutes( 2*device.Interval + 1 ) ), false );
+ xPLCache->updateEntry( "config." + source + ".current", "true", false );
+ }
- xPL_NameValueListPtr nvList = xPL_getMessageBody( message );
- xPL_NameValuePairPtr nvPair = NULL;
- int nvCount = xPL_getNamedValueCount(nvList);
- string multiKey;
- int multiCount = 0;
- for( int nvIndex = 0; nvIndex < nvCount; nvIndex++ )
- {
- nvPair = xPL_getNamedValuePairAt( nvList, nvIndex );
- string value = nvPair->itemValue; to_lower( value );
- string key = nvPair->itemName ; to_lower( key );
- string count = xPLCache->objectValue( "config." + source + ".options." + key + ".count" );
- if( "" != count )
- {
- if( multiKey == key )
- multiCount++;
- ...
[truncated message content] |
|
From: <tho...@us...> - 2011-11-20 21:31:07
|
Revision: 535
http://openautomation.svn.sourceforge.net/openautomation/?rev=535&view=rev
Author: thomas_s
Date: 2011-11-20 21:31:00 +0000 (Sun, 20 Nov 2011)
Log Message:
-----------
- added removed global vars from devicemanager to enable unit testing with mock objects
- implemented first unittest
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
xPLHAL/branches/thomas_s_dev/src/devicemanager.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/xplcache.h
xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp
xPLHAL/branches/thomas_s_dev/src/xplhandler.h
xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
Added Paths:
-----------
xPLHAL/branches/thomas_s_dev/src/i_devicemanager.h
xPLHAL/branches/thomas_s_dev/src/i_xplcache.h
xPLHAL/branches/thomas_s_dev/src/i_xplhandler.h
xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
Removed Paths:
-------------
xPLHAL/branches/thomas_s_dev/test/test_test.cpp
Modified: xPLHAL/branches/thomas_s_dev/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/CMakeLists.txt 2011-11-20 21:29:50 UTC (rev 534)
+++ xPLHAL/branches/thomas_s_dev/CMakeLists.txt 2011-11-20 21:31:00 UTC (rev 535)
@@ -24,7 +24,7 @@
#set(CMAKE_CXX_COMPILER lsbc++)
message("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
-set(create_STATIC_build ON)
+set(create_STATIC_build OFF)
if(create_STATIC_build)
message("Creating a static build...")
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2011-11-20 21:29:50 UTC (rev 534)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2011-11-20 21:31:00 UTC (rev 535)
@@ -18,7 +18,7 @@
cmake_minimum_required(VERSION 2.6)
#set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
-set(CMAKE_CXX_FLAGS "-g -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp xhcp.cpp main.cpp)
add_executable(xPLHAL ${xPLHAL_SRCS})
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2011-11-20 21:29:50 UTC (rev 534)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2011-11-20 21:31:00 UTC (rev 535)
@@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
#include <cstdio>
@@ -24,75 +25,57 @@
#include "log.h"
#include "devicemanager.h"
+#include "i_xplcache.h"
using namespace boost::posix_time;
-void deviceManagerClass::add( const xPLDevice& device ) const
+deviceManagerClass::deviceManagerClass(IxPLHandler* xplhandler, IxPLCacheClass* xplcache)
+:m_xPL(xplhandler)
+,m_xPLCache(xplcache)
{
- writeLog( "deviceManagerClass::add("+device.VDI+")", logLevel::debug );
- if( contains( device.VDI ) ) {
- update( device );
- } else {
- std::string newtag = "device." + device.VDI + ".";
- ptime expires = second_clock::local_time() + minutes( 2*device.Interval + 1 );
+}
- xPLCache->updateEntry(newtag + "vdi", device.VDI, false);
- xPLCache->updateEntry(newtag + "configdone", device.ConfigDone?"true":"false", false);
- xPLCache->updateEntry(newtag + "configmissing", device.ConfigMissing?"true":"false", false);
- xPLCache->updateEntry(newtag + "configsource", device.ConfigSource, false);
- xPLCache->updateEntry(newtag + "configtype", device.ConfigType?"true":"false", false);
- xPLCache->updateEntry(newtag + "waitingconfig", device.WaitingConfig?"true":"false", false);
- xPLCache->updateEntry(newtag + "current", device.Current?"true":"false", false);
- xPLCache->updateEntry(newtag + "configlistsent", device.ConfigListSent?"true":"false", false);
- xPLCache->updateEntry(newtag + "suspended", device.Suspended?"true":"false", false);
- xPLCache->updateEntry(newtag + "interval", lexical_cast<std::string>(device.Interval), false);
- xPLCache->updateEntry(newtag + "expires", timeConverter( expires ), false);
+void deviceManagerClass::add( const xPLDevice& device )
+{
+ writeLog("deviceManagerClass::add(" + device.VDI + ")", logLevel::debug);
+ if (contains( device.VDI )) {
+ mDeviceMap[device.VDI] = device;
+ } else {
+ mDeviceMap[device.VDI] = device;
+ mDeviceMap[device.VDI].Expires = calculateExpireTime(device.Interval);
}
}
-bool deviceManagerClass::remove( const std::string& deviceTag ) const
+bool deviceManagerClass::remove( const std::string& deviceTag )
{
writeLog( "deviceManagerClass::remove("+deviceTag+")", logLevel::debug );
- if( contains( deviceTag ) ) {
- std::vector<std::string> list = xPLCache->childNodes( "device." + deviceTag );
- //for( std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); it++ )
- for( auto it : list )
- xPLCache->deleteEntry( it );
+ auto device = mDeviceMap.find(deviceTag);
+ if (device != mDeviceMap.end()) {
+ mDeviceMap.erase(device);
return true;
- } else {
- return false;
}
+ return false;
}
bool deviceManagerClass::removeConfig( const std::string& deviceTag ) const
{
writeLog( "deviceManagerClass::remove("+deviceTag+")", logLevel::debug );
if( containsConfig( deviceTag ) ) {
- std::vector<std::string> list = xPLCache->childNodes( "config." + deviceTag );
- //for( std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); it++ )
- for (auto it : list)
- xPLCache->deleteEntry( it );
+ std::vector<std::string> list = m_xPLCache->childNodes( "config." + deviceTag );
+ for (auto listitem : list) {
+ m_xPLCache->deleteEntry(listitem);
+ }
return true;
- } else {
- return false;
}
+ return false;
}
xPLDevice deviceManagerClass::getDevice( const std::string& deviceTag ) const
{
xPLDevice retval;
- if( contains( deviceTag ) ) {
- retval.ConfigDone = xPLCache->objectValue( "device." + deviceTag + ".configdone" ) == "true";
- retval.ConfigMissing = xPLCache->objectValue( "device." + deviceTag + ".configmissing" ) == "true";
- retval.ConfigSource = xPLCache->objectValue( "device." + deviceTag + ".configsource" );
- retval.ConfigType = xPLCache->objectValue( "device." + deviceTag + ".configtype" ) == "true";
- retval.Current = xPLCache->objectValue( "device." + deviceTag + ".current" ) == "true";
- retval.Expires = timeConverter( xPLCache->objectValue( "device." + deviceTag + ".expires" ) );
- retval.Interval = atoi(xPLCache->objectValue( "device." + deviceTag + ".interval" ).c_str());
- retval.VDI = xPLCache->objectValue( "device." + deviceTag + ".vdi" );
- retval.WaitingConfig = xPLCache->objectValue( "device." + deviceTag + ".waitingconfig" ) == "true";
- retval.ConfigListSent = xPLCache->objectValue( "device." + deviceTag + ".configlistsent" ) == "true";
- retval.Suspended = xPLCache->objectValue( "device." + deviceTag + ".suspended" ) == "true";
+ auto device = mDeviceMap.find(deviceTag);
+ if (device != mDeviceMap.end()) {
+ retval = device->second;
}
return retval;
}
@@ -100,42 +83,24 @@
std::vector<std::string> deviceManagerClass::getAllDeviceNames() const
{
std::vector<std::string> retval;
- std::vector<std::string> nodes = xPLCache->childNodes( "device." );
-// for( std::vector<std::string>::iterator it = nodes.begin(); it != nodes.end(); ++it )
- for (auto node : nodes) {
- if( ends_with( node, ".vdi" ) ) {
- retval.push_back( node.substr( 7, node.size() - 7 - 4 ) ); // leave "device." and ".vdi" away
- writeLog( "deviceManagerClass::getAllDeviceNames() = "+ node.substr( 7, node.size() - 7 - 4 ), logLevel::debug );
- }
+ retval.reserve(mDeviceMap.size());
+ for (auto node : mDeviceMap) {
+ retval.push_back(node.first);
+ writeLog( "deviceManagerClass::getAllDeviceNames() = "+ node.first, logLevel::debug );
}
return retval;
}
-void deviceManagerClass::update( const xPLDevice& device ) const
+void deviceManagerClass::processConfigList( const xPL_MessagePtr message )
{
- writeLog( "deviceManagerClass::update("+device.VDI+") - known: "+ (contains( device.VDI )?"true":"false"), logLevel::debug );
-
- if( contains( device.VDI ) ) {
- remove( device.VDI );
- }
- writeLog( "deviceManagerClass::update("+device.VDI+") -> add", logLevel::debug );
- add( device );
-}
-
-void deviceManagerClass::processConfigList( const xPL_MessagePtr message ) const
-{
- std::string source = std::string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
+ std::string source = extractSourceFromXplMessage(message);
xPLDevice device = getDevice( source );
writeLog( "deviceManagerClass::processConfigList("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
// A config list turned up that we haven't asked for...
// create a new device...
- const char* intervalString = xPL_getMessageNamedValue( message, "interval" );
- int interval = intervalString ? atoi(intervalString) : 5; // default to 5 minutes
- ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
+ int interval = 5;
+ ptime expires = calculateExpireTime(xPL_getMessageNamedValue(message, "interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = false; // true = no config file, no response from device, false = have/waiting config
@@ -147,57 +112,70 @@
device.Suspended = false; // lost heartbeat
device.Interval = interval; // current heartbeat interval
device.Expires = expires; // time expires
- update( device );
+ mDeviceMap[device.VDI] = device;
}
xPL_NameValueListPtr nvList = xPL_getMessageBody( message );
xPL_NameValuePairPtr nvPair = NULL;
int nvCount = xPL_getNamedValueCount(nvList);
- for( int nvIndex = 0; nvIndex < nvCount; nvIndex++ ) {
+ for (int nvIndex = 0; nvIndex < nvCount; nvIndex++ ) {
std::string newtag = "config." + source + ".options.";
nvPair = xPL_getNamedValuePairAt( nvList, nvIndex );
std::string value = nvPair->itemValue; to_lower( value );
std::string key = nvPair->itemName ; to_lower( key );
boost::regex re( "([a-z0-9]{1,16})\\[(\\d{1,3})\\]" );
boost::smatch matches;
- if( boost::regex_match( value, matches, re) ) {
- xPLCache->updateEntry( newtag + matches[1] , "" , false );
- xPLCache->updateEntry( newtag + matches[1] + ".type" , key , false );
- xPLCache->updateEntry( newtag + matches[1] + ".count", matches[2], false );
- } else {
- xPLCache->updateEntry( newtag + value , "" , false );
- xPLCache->updateEntry( newtag + value + ".type" , key , false );
- xPLCache->updateEntry( newtag + value + ".count", "" , false );
+ if (boost::regex_match(value, matches, re)) {
+ m_xPLCache->updateEntry( newtag + matches[1] , "" , false );
+ m_xPLCache->updateEntry( newtag + matches[1] + ".type" , key , false );
+ m_xPLCache->updateEntry( newtag + matches[1] + ".count", matches[2], false );
+ }
+ else {
+ m_xPLCache->updateEntry( newtag + value , "" , false );
+ m_xPLCache->updateEntry( newtag + value + ".type" , key , false );
+ m_xPLCache->updateEntry( newtag + value + ".count", "" , false );
}
}
// send the config response, but only if we have a config (e.g. from the use via XHCP)
- if( xPLCache->exists( "config." + source + ".current" ) ) {
- xPLCache->updateEntry( "device." + source + ".configdone", "true", false );
+ if( m_xPLCache->exists( "config." + source + ".current" ) ) {
+ mDeviceMap[source].ConfigDone = true;
sendConfigResponse( source, false );
- } else {
+ }
+ else {
// try to get at least the current config
xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
- xPL->sendMessage( xPL_MESSAGE_COMMAND,
+ m_xPL->sendMessage( xPL_MESSAGE_COMMAND,
xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
"config", "current", command_request );
}
}
-void deviceManagerClass::processConfigHeartBeat( const xPL_MessagePtr message ) const
+ptime deviceManagerClass::calculateExpireTime(const char* string_interval, int *pInterval)
{
- std::string source = std::string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
+ int interval = string_interval ? atoi(string_interval) : 5; // default to 5 minutes
+ if (pInterval) {
+ *pInterval = interval;
+ }
+ return calculateExpireTime(interval);
+}
+
+ptime deviceManagerClass::calculateExpireTime(int interval)
+{
+ return second_clock::local_time() + minutes( 2* interval + 1 );
+}
+
+void deviceManagerClass::processConfigHeartBeat( const xPL_MessagePtr message )
+{
+ std::string source = extractSourceFromXplMessage(message);
+
xPLDevice device = getDevice( source );
writeLog( "deviceManagerClass::processConfigHeartBeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
- if( "" == device.VDI ) {
+ if( device.VDI.empty() ) {
// this handles a new application that identifies itself with a hbeat straight away.
// it must either be storing it's config locally, can't be configured, or is configured somewhere else.
- const char* intervalString = xPL_getMessageNamedValue( message, "interval" );
- int interval = intervalString ? atoi(intervalString) : 5; // default to 5 minutes
- ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
+ int interval = 5;
+ ptime expires = calculateExpireTime(xPL_getMessageNamedValue(message, "interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = true; // true = no config file, no response from device, false = have/waiting config
@@ -209,29 +187,27 @@
device.Suspended = false; // lost heartbeat
device.Interval = interval; // current heartbeat interval
device.Expires = expires; // time expires
- update( device );
+ mDeviceMap[device.VDI] = device;
} else {
- xPLCache->updateEntry( "device." + source + ".expires", timeConverter( second_clock::local_time() + minutes( 2*device.Interval + 1 ) ), false );
+ mDeviceMap[device.VDI].Expires = calculateExpireTime(device.Interval);
+ mDeviceMap[device.VDI].ConfigSource = "objectcache";
// FIXME - that line look like that in the VB code - but it seems really strange!
- xPLCache->updateEntry( "device." + source + ".expires.configdone", "objectcache", false );
+// m_xPLCache->updateEntry( "device." + source + ".expires.configdone", "objectcache", false );
}
// ask device for configuration (if haven't asked it before...)
if( !device.ConfigListSent ) {
xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
- xPL->sendMessage( xPL_MESSAGE_COMMAND,
+ m_xPL->sendMessage( xPL_MESSAGE_COMMAND,
xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
"config", "list", command_request );
- xPLCache->updateEntry( "device." + source + ".configlistsend", "true", false );
+ mDeviceMap[device.VDI].ConfigListSent = true;
}
}
-void deviceManagerClass::processCurrentConfig( const xPL_MessagePtr message ) const
+void deviceManagerClass::processCurrentConfig( const xPL_MessagePtr message )
{
- std::string source = std::string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
+ std::string source = extractSourceFromXplMessage(message);
xPLDevice device = getDevice( source );
writeLog( "deviceManagerClass::processCurrentConfig("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
@@ -240,8 +216,9 @@
// => just treat it like an heartbeat
return processConfigHeartBeat( message );
} else {
- xPLCache->updateEntry( "config." + source + ".expires", timeConverter( second_clock::local_time() + minutes( 2*device.Interval + 1 ) ), false );
- xPLCache->updateEntry( "config." + source + ".current", "true", false );
+// ptime expires = calculateExpireTime(device.Interval);
+// m_xPLCache->updateEntry( "config." + source + ".expires", timeConverter(calculateExpireTime(device.Interval), false ));
+ m_xPLCache->updateEntry( "config." + source + ".current", "true", false );
}
xPL_NameValueListPtr nvList = xPL_getMessageBody( message );
@@ -253,7 +230,7 @@
nvPair = xPL_getNamedValuePairAt( nvList, nvIndex );
std::string value = nvPair->itemValue; to_lower( value );
std::string key = nvPair->itemName ; to_lower( key );
- std::string count = xPLCache->objectValue( "config." + source + ".options." + key + ".count" );
+ std::string count = m_xPLCache->objectValue( "config." + source + ".options." + key + ".count" );
if( "" != count ) {
if( multiKey == key ) {
multiCount++;
@@ -265,20 +242,25 @@
snprintf( buf, 6, "{%.3d}", multiCount );
key += buf;
}
- xPLCache->updateEntry( "config." + source + ".current." + key, value, false );
+ m_xPLCache->updateEntry( "config." + source + ".current." + key, value, false );
}
}
-void deviceManagerClass::processHeartbeat( xPL_MessagePtr message ) const
+std::string deviceManagerClass::extractSourceFromXplMessage( xPL_MessagePtr message )
{
- std::string source = std::string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
+ return std::string(xPL_getSourceVendor(message)) + "-"
+ + xPL_getSourceDeviceID ( message ) + "."
+ + xPL_getSourceInstanceID( message );
+}
+
+void deviceManagerClass::processHeartbeat( xPL_MessagePtr message )
+{
+ std::string source = extractSourceFromXplMessage(message);
+
xPLDevice device = getDevice( source );
- int interval = atoi(std::string( xPL_getMessageNamedValue( message, "interval" ) ).c_str());
- ptime expires = second_clock::local_time() + minutes( 2*interval + 1 );
+ int interval = 5;
+ ptime expires = calculateExpireTime(xPL_getMessageNamedValue(message, "interval"), &interval);
writeLog( "deviceManagerClass::processHeartbeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
@@ -295,56 +277,52 @@
device.Suspended = false; // lost heartbeat
device.Interval = interval; // current heartbeat interval
device.Expires = expires; // time expires
- update( device );
+ mDeviceMap[device.VDI] = device;
// Throw it a config request anyway, see what turns up..
xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
- xPL->sendMessage( xPL_MESSAGE_COMMAND,
+ m_xPL->sendMessage( xPL_MESSAGE_COMMAND,
xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
"config", "list" , command_request );
/* // that code below was from the VB - but we don't need it as processConfigList will
// itself send the config.current request...
- xPL->sendMessage( xPL_MESSAGE_COMMAND,
+ m_xPL->sendMessage( xPL_MESSAGE_COMMAND,
xPL_getSourceVendor( message ), xPL_getSourceDeviceID( message ), xPL_getSourceInstanceID( message ),
"config", "current", command_request );
*/
} else {
- xPLCache->updateEntry( "device." + source + ".expires", timeConverter( expires ), false );
+ mDeviceMap[source].Expires = expires;
}
}
-void deviceManagerClass::processRemove( xPL_MessagePtr message ) const
+void deviceManagerClass::processRemove( xPL_MessagePtr message )
{
- std::string source = std::string("")
- + xPL_getSourceVendor ( message ) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
+ std::string source = extractSourceFromXplMessage(message);
remove( source );
removeConfig( source );
}
-void deviceManagerClass::sendConfigResponse( const std::string& source, const bool removeOldValue ) const
+void deviceManagerClass::sendConfigResponse( const std::string& source, const bool removeOldValue )
{
writeLog( "deviceManagerClass::sendConfigResponse("+source+", "+(removeOldValue?"true":"false")+")", logLevel::debug );
boost::regex re( "config\\." + source + "\\.current\\.([a-z0-9]{1,16})(?:\\{([0-9]{1,3})\\})?" );
- std::vector<std::string> entries = xPLCache->filterByRegEx( re );
+ std::vector<std::string> entries = m_xPLCache->filterByRegEx( re );
xPLMessage::namedValueList list;
-// for( std::vector<std::string>::const_iterator it = entries.begin(); it != entries.end(); ++it )
for( auto entry : entries) {
boost::smatch matches;
boost::regex_match( entry, matches, re );
writeLog( "deviceManagerClass::sendConfigResponse: ["+entry+"] -> ["+matches[1]+"]("+matches[2]+")",logLevel::debug );
if( matches.size() > 1 ) {
- list.push_back( std::make_pair( matches[1], xPLCache->objectValue( entry ) ) );
+ list.push_back( std::make_pair( matches[1], m_xPLCache->objectValue( entry ) ) );
}
}
if( list.size() > 0 ) {
- xPL->sendMessage( xPL_MESSAGE_COMMAND, source, "config", "response", list );
- xPLCache->updateEntry( "config." + source + ".configmissing", "false", false );
- xPLCache->updateEntry( "config." + source + ".waitingconfig", "false", false );
- xPLCache->updateEntry( "config." + source + ".configdone" , "true" , false ); // FIXME the VB code says "false"...
+ m_xPL->sendMessage( xPL_MESSAGE_COMMAND, source, "config", "response", list );
+ m_xPLCache->updateEntry( "config." + source + ".configmissing", "false", false );
+ m_xPLCache->updateEntry( "config." + source + ".waitingconfig", "false", false );
+ m_xPLCache->updateEntry( "config." + source + ".configdone" , "true" , false ); // FIXME the VB code says "false"...
}
if( removeOldValue ) {
@@ -353,24 +331,24 @@
}
}
-bool deviceManagerClass::storeNewConfig( const std::string& source, const std::string& config ) const
+bool deviceManagerClass::storeNewConfig( const std::string& source, const std::string& config )
{
writeLog( "deviceManagerClass::storeNewConfig("+source+", "+config+")", logLevel::debug );
- if( !contains( source ) ) {
+ auto device = mDeviceMap.find(source);
+ if (device == mDeviceMap.end()) {
return false;
}
std::vector<std::string> list;
split( list, config, is_any_of("\r\n"), token_compress_on );
std::string multiKey;
- int multiCount = 0;
-// for( std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it )
- for( auto it : list) {
+ int multiCount = 0;
+ for( auto listitem : list) {
std::vector<std::string> tags;
- split( tags, it, is_any_of("=") );
+ split( tags, listitem, is_any_of("=") );
to_lower( tags[0] );
to_lower( tags[1] );
- std::string count = xPLCache->objectValue( "config." + source + ".options." + tags[0] + ".count" );
+ std::string count = m_xPLCache->objectValue( "config." + source + ".options." + tags[0] + ".count" );
if( "" != count ) {
if( multiKey != tags[0] ) {
multiKey = tags[0];
@@ -383,10 +361,21 @@
snprintf( buf, 6, "{%.3d}", multiCount );
tags[0] += buf;
}
- xPLCache->updateEntry( "config." + source + ".current." + tags[0], tags[1], false );
+ m_xPLCache->updateEntry( "config." + source + ".current." + tags[0], tags[1], false );
}
- if( xPLCache->childNodes( "config." + source + ".current" ).size() > 0 ) {
+ if( m_xPLCache->childNodes( "config." + source + ".current" ).size() > 0 ) {
sendConfigResponse( source, false ); // FIXME the VB said true - but why should I delete the values that I've just stored?
}
return true;
}
+
+bool deviceManagerClass::contains( const std::string& deviceTag ) const
+{
+ return mDeviceMap.find(deviceTag) != mDeviceMap.end();
+}
+
+bool deviceManagerClass::containsConfig( const std::string& configTag ) const
+{
+ return m_xPLCache->childNodes( "config." + configTag ).size() > 0;
+}
+
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2011-11-20 21:29:50 UTC (rev 534)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2011-11-20 21:31:00 UTC (rev 535)
@@ -20,52 +20,65 @@
#define DEVICEMANAGER_H
#include <string>
+#include <map>
// this is also including the xPL.h with its data structures:
#include "xplhandler.h"
+class IxPLHandler;
+class IxPLCacheClass;
+
#include "xplcache.h"
#include "globals.h"
#include "xpldevice.h"
+#include "i_devicemanager.h"
-class deviceManagerClass
+class deviceManagerClass: public IdeviceManagerClass
{
- public:
- /** \brief Looks if the device deviceTag is known. */
- bool contains( const std::string& deviceTag ) const
- { return xPLCache->childNodes( "device." + deviceTag ).size() > 0; }
+ public:
+ deviceManagerClass(IxPLHandler* xplhandler, IxPLCacheClass* xplcache);
- /** \brief Looks if the config configTag is known. */
- bool containsConfig( const std::string& configTag ) const
- { return xPLCache->childNodes( "config." + configTag ).size() > 0; }
+ /** \brief Looks if the device deviceTag is known. */
+ bool contains( const std::string& deviceTag ) const;
- void add( const xPLDevice& device ) const;
- bool remove( const std::string& deviceTag ) const;
- bool removeConfig( const std::string& deviceTag ) const;
+ /** \brief Looks if the config configTag is known. */
+ bool containsConfig( const std::string& configTag ) const;
- /** \brief Returns the device deviceTag when it's known or an empty device */
- xPLDevice getDevice( const std::string& deviceTag ) const;
+ void add( const xPLDevice& device );
+ bool remove( const std::string& deviceTag );
+ bool removeConfig( const std::string& deviceTag ) const;
- /** \brief Returns all known device names */
- std::vector<std::string> getAllDeviceNames() const;
+ /** \brief Returns the device deviceTag when it's known or an empty device */
+ xPLDevice getDevice( const std::string& deviceTag ) const;
- void update( const xPLDevice& device ) const;
+ /** \brief Returns all known device names */
+ std::vector<std::string> getAllDeviceNames() const;
- /** \brief Handle the returned config list that someone (porbably we) have asked for */
- void processConfigList ( const xPL_MessagePtr message ) const;
+ /** \brief Handle the returned config list that someone (porbably we) have asked for */
+ void processConfigList ( const xPL_MessagePtr message );
- /** \brief Called when a new device poped up and is waiting to be configured */
- void processConfigHeartBeat( const xPL_MessagePtr message ) const;
+ /** \brief Called when a new device poped up and is waiting to be configured */
+ void processConfigHeartBeat( const xPL_MessagePtr message );
- /** \brief Called when a device sends its configuration */
- void processCurrentConfig ( const xPL_MessagePtr message ) const;
- void processHeartbeat ( const xPL_MessagePtr message ) const;
- void processRemove ( const xPL_MessagePtr message ) const;
+ /** \brief Called when a device sends its configuration */
+ void processCurrentConfig ( const xPL_MessagePtr message );
+ void processHeartbeat ( const xPL_MessagePtr message );
+ void processRemove ( const xPL_MessagePtr message );
- void sendConfigResponse( const std::string& source, const bool removeOldValue ) const;
-
- /** \brief A new configuration arrived via XHCP, handle it... */
- bool storeNewC...
[truncated message content] |
|
From: <tho...@us...> - 2011-12-19 21:35:22
|
Revision: 601
http://openautomation.svn.sourceforge.net/openautomation/?rev=601&view=rev
Author: thomas_s
Date: 2011-12-19 21:35:14 +0000 (Mon, 19 Dec 2011)
Log Message:
-----------
- more refactoring
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
xPLHAL/branches/thomas_s_dev/src/devicemanager.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp
xPLHAL/branches/thomas_s_dev/src/xplhandler.h
xPLHAL/branches/thomas_s_dev/src/xplmessage.h
xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
Added Paths:
-----------
xPLHAL/branches/thomas_s_dev/src/xplmessage.cpp
xPLHAL/branches/thomas_s_dev/test/mock_xplhandler.h
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2011-12-19 21:35:14 UTC (rev 601)
@@ -19,7 +19,7 @@
#set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
-set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp xhcp.cpp main.cpp)
+set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp xhcp.cpp xplmessage.cpp main.cpp)
add_executable(xPLHAL ${xPLHAL_SRCS})
#message(STATUS "Boost_LIBRARIES=${Boost_LIBRARIES}")
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2011-12-19 21:35:14 UTC (rev 601)
@@ -15,8 +15,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
#include <cstdio>
@@ -125,16 +123,14 @@
void deviceManagerClass::processConfigList( const xPLMessagePtr message )
{
- std::string source = extractSourceFromXplMessage(message);
+ std::string source = message->getSourceVDI();
xPLDevice device = getDevice( source );
writeLog( "deviceManagerClass::processConfigList("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
// A config list turned up that we haven't asked for...
// create a new device...
int interval = 5;
- //\TODO: implement xPL_getMessageNamedValue
-// ptime expires = calculateExpireTime(xPL_getMessageNamedValue(message, "interval"), &interval);
- ptime expires = calculateExpireTime("5", &interval);
+ ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = false; // true = no config file, no response from device, false = have/waiting config
@@ -178,18 +174,16 @@
// try to get at least the current config
xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
xPLMessagePtr msg( new xPLMessage(xPL_MESSAGE_COMMAND,
- message->vendor,
- message->deviceID,
- message->instanceID,
+ source,
"config", "current",
command_request) );
m_sigSendXplMessage(msg);
}
}
-ptime deviceManagerClass::calculateExpireTime(const char* string_interval, int *pInterval)
+ptime deviceManagerClass::calculateExpireTime(const std::string& string_interval, int *pInterval)
{
- int interval = string_interval ? atoi(string_interval) : 5; // default to 5 minutes
+ int interval = string_interval.empty() ? atoi(string_interval.c_str()) : 5; // default to 5 minutes
if (pInterval) {
*pInterval = interval;
}
@@ -203,7 +197,7 @@
void deviceManagerClass::processConfigHeartBeat( const xPLMessagePtr message )
{
- std::string source = extractSourceFromXplMessage(message);
+ std::string source = message->getSourceVDI();
xPLDevice device = getDevice( source );
writeLog( "deviceManagerClass::processConfigHeartBeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
@@ -211,9 +205,7 @@
// this handles a new application that identifies itself with a hbeat straight away.
// it must either be storing it's config locally, can't be configured, or is configured somewhere else.
int interval = 5;
- //\TODO
-// ptime expires = calculateExpireTime(xPL_getMessageNamedValue(message, "interval"), &interval);
- ptime expires = calculateExpireTime("5", &interval);
+ ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = true; // true = no config file, no response from device, false = have/waiting config
@@ -237,9 +229,7 @@
if( !device.ConfigListSent ) {
xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
xPLMessagePtr msg( new xPLMessage(xPL_MESSAGE_COMMAND,
- message->vendor,
- message->deviceID,
- message->instanceID,
+ source,
"config", "list",
command_request) );
m_sigSendXplMessage(msg);
@@ -249,7 +239,7 @@
void deviceManagerClass::processCurrentConfig( const xPLMessagePtr message )
{
- std::string source = extractSourceFromXplMessage(message);
+ std::string source = message->getSourceVDI();
xPLDevice device = getDevice( source );
writeLog( "deviceManagerClass::processCurrentConfig("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
@@ -286,29 +276,13 @@
}
}
-std::string deviceManagerClass::extractSourceFromXplMessage( xPL_MessagePtr message )
-{
- return std::string(xPL_getSourceVendor(message)) + "-"
- + xPL_getSourceDeviceID ( message ) + "."
- + xPL_getSourceInstanceID( message );
-}
-
-std::string deviceManagerClass::extractSourceFromXplMessage( xPLMessagePtr message )
-{
- return std::string(message->vendor + "-"
- + message->deviceID + "."
- + message->instanceID);
-}
-
void deviceManagerClass::processHeartbeat( xPLMessagePtr message )
{
- std::string source = extractSourceFromXplMessage(message);
+ std::string source = message->getSourceVDI();
xPLDevice device = getDevice( source );
int interval = 5;
- //\TODO
-// ptime expires = calculateExpireTime(xPL_getMessageNamedValue(message, "interval"), &interval);
- ptime expires = calculateExpireTime("5", &interval);
+ ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
writeLog( "deviceManagerClass::processHeartbeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
@@ -330,9 +304,7 @@
// Throw it a config request anyway, see what turns up..
xPLMessage::namedValueList command_request; command_request.push_back( std::make_pair( "command", "request" ) );
xPLMessagePtr msg( new xPLMessage(xPL_MESSAGE_COMMAND,
- message->vendor,
- message->deviceID,
- message->instanceID,
+ source,
"config", "list",
command_request) );
m_sigSendXplMessage(msg);
@@ -349,7 +321,7 @@
void deviceManagerClass::processRemove( xPLMessagePtr message )
{
- std::string source = extractSourceFromXplMessage(message);
+ std::string source = message->getSourceVDI();
remove( source );
removeConfig( source );
@@ -371,15 +343,8 @@
}
if( list.size() > 0 ) {
- size_t marker1 = source.find( "-" );
- size_t marker2 = source.find( "." );
- std::string vendor = source.substr( 0, marker1 );
- std::string device = source.substr( marker1+1, marker2 - (marker1+1) );
- std::string instance = source.substr( marker2+1 );
xPLMessagePtr msg( new xPLMessage(xPL_MESSAGE_COMMAND,
- vendor,
- device,
- instance,
+ source,
"config", "response",
list) );
m_sigSendXplMessage(msg);
@@ -442,7 +407,3 @@
return m_xPLCache->childNodes( "config." + configTag ).size() > 0;
}
-boost::signals2::connection deviceManagerClass::connect(const xPLHandler::signal_t::slot_type &subscriber)
-{
- return m_sigSendXplMessage.connect(subscriber);
-}
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2011-12-19 21:35:14 UTC (rev 601)
@@ -32,8 +32,6 @@
public:
deviceManagerClass(IxPLCacheClass* xplcache);
- boost::signals2::connection connect(const xPLHandler::signal_t::slot_type &subscriber);
-
/** \brief Looks if the device deviceTag is known. */
bool contains( const std::string& deviceTag ) const;
@@ -68,16 +66,12 @@
/** \brief A new configuration arrived via XHCP, handle it... */
bool storeNewConfig( const std::string& source, const std::string& config );
-
+
+ xPLHandler::signal_t m_sigSendXplMessage;
private:
- /*! \TODO: move to correct class, maybe xplMessage */
- std::string extractSourceFromXplMessage( xPL_MessagePtr message );
- std::string extractSourceFromXplMessage( xPLMessagePtr message );
-
boost::posix_time::ptime calculateExpireTime(int interval);
- boost::posix_time::ptime calculateExpireTime(const char* string_interval, int *pInterval = 0);
+ boost::posix_time::ptime calculateExpireTime(const std::string& string_interval, int *pInterval = 0);
IxPLCacheClass* m_xPLCache;
std::map<std::string, xPLDevice> mDeviceMap;
- xPLHandler::signal_t m_sigSendXplMessage;
};
Modified: xPLHAL/branches/thomas_s_dev/src/main.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/main.cpp 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/main.cpp 2011-12-19 21:35:14 UTC (rev 601)
@@ -108,7 +108,8 @@
XHCPServer *xhcpServer = new XHCPServer();
xPL = new xPLHandler( boost::asio::ip::host_name() ); //xPL->start();
deviceManager = new deviceManagerClass(xPLCache);
- xPL->connect(boost::bind(&deviceManagerClass::processXplMessage, deviceManager, _1));
+ deviceManager->m_sigSendXplMessage.connect(boost::bind(&xPLMessageQueueClass::add, xPLMessageQueue, _1));
+ xPL->m_sigRceivedXplMessage.connect(boost::bind(&deviceManagerClass::processXplMessage, deviceManager, _1));
writeLog( "started", logLevel::all );
// force everyone to send their configuration so that we start up to date...
Modified: xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp 2011-12-19 21:35:14 UTC (rev 601)
@@ -152,83 +152,6 @@
xPLMessageQueue->add( xPLMessagePtr( new xPLMessage( type, vendor, device, instance, msgClass, msgType, namedValues ) ) );
}
-void xPLHandler::printXPLMessage( xPL_MessagePtr theMessage )
-{
- std::string result;
-
- /* Source Info */
- result += xPL_getSourceVendor(theMessage) + std::string("-");
- result += xPL_getSourceDeviceID(theMessage) + std::string(".");
- result += xPL_getSourceInstanceID(theMessage);
-
- result += " -> ";
- /* Handle various target types */
- if (xPL_isBroadcastMessage(theMessage)) {
- result += "*";
- } else {
- if (xPL_isGroupMessage(theMessage)) {
- result += "XPL-GROUP.";
- result += xPL_getTargetGroup(theMessage);
- } else {
- result += xPL_getTargetVendor(theMessage) + std::string("-");
- result += xPL_getTargetDeviceID(theMessage) + std::string(".");
- result += xPL_getTargetInstanceID(theMessage);
- }
- }
-
- /* Print hop count */
- result += " (";
- result += lexical_cast<std::string>(xPL_getHopCount(theMessage));
- result += " hops) ";
-
- result += "[";
- switch(xPL_getMessageType(theMessage))
- {
- case xPL_MESSAGE_COMMAND:
- result += "xpl-cmnd";
- break;
- case xPL_MESSAGE_STATUS:
- result += "xpl-stat";
- break;
- case xPL_MESSAGE_TRIGGER:
- result += "xpl-trig";
- break;
- default:
- result += "!UNKNOWN!";
- break;
- }
- result += "] ";
-
- /* Echo Schema Info */
- result += xPL_getSchemaClass(theMessage) + std::string(".");
- result += xPL_getSchemaType(theMessage) + std::string(": ");
-
- xPL_NameValueListPtr nvList = xPL_getMessageBody(theMessage);
- xPL_NameValuePairPtr nvPair = NULL;
- int nvIndex = 0;
- int nvCount = xPL_getNamedValueCount(nvList);
- /* Write Name/Value Pairs out */
- for (nvIndex = 0; nvIndex < nvCount; nvIndex++) {
- nvPair = xPL_getNamedValuePairAt(nvList, nvIndex);
- result += nvPair->itemName; //WRITE_TEXT(nvPair->itemName);
- result += "="; //WRITE_TEXT("=");
-
- /* Write data content out */
- if (nvPair->itemValue != NULL) {
- if (nvPair->isBinary)
- ;//writeBinaryValue(nvPair->itemValue, nvPair->binaryLength);
- else
- result += nvPair->itemValue; //WRITE_TEXT(nvPair->itemValue);
- }
-
- /* Terminate line/entry */
- result += "\n"; //WRITE_TEXT("\n");
- }
- replace_all( result, "\n", ";" );
-
- writeLog( result, logLevel::debug );
-}
-
void xPLHandler::xpl_message_callback( xPL_MessagePtr theMessage, void *userValue )
{
xPLHandler* obj = static_cast<xPLHandler*>(userValue);
@@ -237,8 +160,6 @@
void xPLHandler::handleXPLMessage( xPL_MessagePtr theMessage)
{
- printXPLMessage( theMessage );
-
xPLMessage::namedValueList values;
xPL_NameValueListPtr nvList = xPL_getMessageBody(theMessage);
xPL_NameValuePairPtr nvPair = NULL;
@@ -260,12 +181,18 @@
xPL_getSchemaType(theMessage),
values) );
- m_sigRceivedXplMessage(msg);
+ msg->isBroadcastMessage = xPL_isBroadcastMessage(theMessage);
+ msg->isGroupMessage = xPL_isGroupMessage(theMessage);
+ if (!msg->isBroadcastMessage) {
+ msg->targetVendor = xPL_getTargetVendor(theMessage);
+ msg->targetDevice = xPL_getTargetDeviceID(theMessage);
+ msg->targetInstance = xPL_getTargetInstanceID(theMessage);
+ }
+ if (msg->isGroupMessage) {
+ msg->targetGroup = xPL_getTargetGroup(theMessage);
+ }
+
+ writeLog(msg->printXPLMessage(), logLevel::debug );
+ m_sigRceivedXplMessage(msg);
}
-
-boost::signals2::connection xPLHandler::connect(const signal_t::slot_type &subscriber)
-{
- return m_sigRceivedXplMessage.connect(subscriber);
-}
-
Modified: xPLHAL/branches/thomas_s_dev/src/xplhandler.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplhandler.h 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/xplhandler.h 2011-12-19 21:35:14 UTC (rev 601)
@@ -42,8 +42,6 @@
xPLHandler( const std::string& host_name);
~xPLHandler();
- boost::signals2::connection connect(const signal_t::slot_type &subscriber);
-
void run();
/** \brief Broadcast one message to the xPL network. */
@@ -57,11 +55,11 @@
/** \brief Send a directed message to the xPL network. */
void sendMessage( const xPL_MessageType type, const std::string& VDI,
const std::string& msgClass, const std::string& msgType, const xPLMessage::namedValueList& namedValues ) const;
+
+ public:
+ signal_t m_sigRceivedXplMessage;
private:
- /** \brief Print via the logging facility the whole content of a xPL message. */
- static void printXPLMessage( xPL_MessagePtr theMessage );
-
/** \brief Handle an incomming xPL message. */
void handleXPLMessage( xPL_MessagePtr theMessage);
@@ -75,5 +73,4 @@
boost::thread* m_thread;
static int m_refcount;
bool m_exit_thread;
- signal_t m_sigRceivedXplMessage;
};
Added: xPLHAL/branches/thomas_s_dev/src/xplmessage.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplmessage.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/xplmessage.cpp 2011-12-19 21:35:14 UTC (rev 601)
@@ -0,0 +1,119 @@
+/*
+ xPLHAL implementation in C++
+ Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "xplmessage.h"
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/lexical_cast.hpp>
+#include <algorithm>
+
+using namespace boost::algorithm;
+using boost::lexical_cast;
+
+std::string xPLMessage::getTypeString() const
+{
+ switch(type)
+ {
+ case xPL_MESSAGE_COMMAND: return "xpl-cmnd";
+ case xPL_MESSAGE_STATUS: return "xpl-stat";
+ case xPL_MESSAGE_TRIGGER: return "xpl-trig";
+ default: return "!UNKNOWN!";
+ }
+}
+
+std::string xPLMessage::getSourceVDI() const
+{
+ return vendor + std::string("-") + deviceID + std::string(".") + instanceID;
+}
+
+std::string xPLMessage::getTargetVDI() const
+{
+ return targetVendor + std::string("-") + targetDevice + std::string(".") + targetInstance;
+}
+
+bool xPLMessage::setSourceFromVDI(const std::string& source)
+{
+ size_t marker1 = source.find( "-" );
+ size_t marker2 = source.find( "." );
+ vendor = source.substr( 0, marker1 );
+ deviceID = source.substr( marker1+1, marker2 - (marker1+1) );
+ instanceID = source.substr( marker2+1 );
+
+ return true;
+}
+
+bool xPLMessage::setTargetFromVDI(const std::string& target)
+{
+ size_t marker1 = target.find( "-" );
+ size_t marker2 = target.find( "." );
+ targetVendor = target.substr( 0, marker1 );
+ targetDevice = target.substr( marker1+1, marker2 - (marker1+1) );
+ targetInstance = target.substr( marker2+1 );
+
+ return true;
+}
+
+std::string xPLMessage::getNamedValue(const std::string& tag) const
+{
+ for (auto entry : namedValues) {
+ if (entry.first == tag) {
+ return entry.second;
+ }
+ }
+ return "";
+}
+
+std::string xPLMessage::printXPLMessage() const
+{
+ std::string result;
+ result += "<" + getTypeString() + " ";
+
+ /* Source Info */
+ result += getSourceVDI();
+ result += " -> ";
+ /* Handle various target types */
+ if (isBroadcastMessage) {
+ result += "*";
+ } else {
+ if (isGroupMessage) {
+ result += "XPL-GROUP." + targetGroup;
+ } else {
+ result += getTargetVDI();
+ }
+ }
+
+ /* Print hop count */
+ result += " (" + lexical_cast<std::string>(hopcount) + " hops) ";
+
+ /* Echo Schema Info */
+ result += "[" + msgClass + "." + msgType + "]: ";
+
+ for (auto entry : namedValues) {
+ result += entry.first + "=" + entry.second + "\n";
+ }
+ replace_all(result, "\n", ";");
+
+ result += ">";
+
+ return result;
+}
+
+std::ostream& operator<<(std::ostream& os, const xPLMessage& msg)
+{
+ os << msg.printXPLMessage();
+ return os;
+}
+
Modified: xPLHAL/branches/thomas_s_dev/src/xplmessage.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplmessage.h 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/src/xplmessage.h 2011-12-19 21:35:14 UTC (rev 601)
@@ -33,30 +33,67 @@
*/
class xPLMessage
{
- public:
- /** \brief Type that contains all name-value pairs of one xPL message.
- * This type has to preserve the order of it's items and must support
- * multiple entries with the same key. So a map or multimap wan't sufficient.
- */
- typedef std::vector<std::pair<std::string,std::string> > namedValueList;
+ public:
+ /** \brief Type that contains all name-value pairs of one xPL message.
+ * This type has to preserve the order of it's items and must support
+ * multiple entries with the same key. So a map or multimap wan't sufficient.
+ */
+ typedef std::vector<std::pair<std::string,std::string> > namedValueList;
- xPL_MessageType type;
- std::string vendor;
- std::string deviceID;
- std::string instanceID;
- std::string msgClass;
- std::string msgType;
- namedValueList namedValues;
+ public:
+ xPL_MessageType type;
+ std::string vendor;
+ std::string deviceID;
+ std::string instanceID;
+ std::string msgClass;
+ std::string msgType;
- xPLMessage(
- const xPL_MessageType _type,
- const std::string& _vendor,
- const std::string& _deviceID,
- const std::string& _instanceID,
- const std::string& _msgClass,
- const std::string& _msgType,
- const namedValueList& _namedValues
- ) : type(_type), vendor(_vendor), deviceID(_deviceID), instanceID(_instanceID),
- msgClass(_msgClass), msgType(_msgType), namedValues(_namedValues) {}
+ namedValueList namedValues;
+
+ bool isBroadcastMessage;
+ bool isGroupMessage;
+
+ std::string targetVendor;
+ std::string targetDevice;
+ std::string targetInstance;
+ std::string targetGroup;
+
+ int hopcount;
+
+ xPLMessage(
+ const xPL_MessageType _type,
+ const std::string& _vendor,
+ const std::string& _deviceID,
+ const std::string& _instanceID,
+ const std::string& _msgClass,
+ const std::string& _msgType,
+ const namedValueList& _namedValues
+ ) : type(_type), vendor(_vendor), deviceID(_deviceID), instanceID(_instanceID),
+ msgClass(_msgClass), msgType(_msgType), namedValues(_namedValues)
+ {
+ }
+
+ xPLMessage(
+ const xPL_MessageType _type,
+ const std::string& _vdi,
+ const std::string& _msgClass,
+ const std::string& _msgType,
+ const namedValueList& _namedValues
+ ) : type(_type), msgClass(_msgClass), msgType(_msgType), namedValues(_namedValues)
+ {
+ setSourceFromVDI(_vdi);
+ }
+
+ std::string printXPLMessage() const;
+ std::string getTypeString() const;
+ std::string getSourceVDI() const;
+ std::string getTargetVDI() const;
+
+ bool setSourceFromVDI(const std::string& vdi);
+ bool setTargetFromVDI(const std::string& vdi);
+
+ std::string getNamedValue(const std::string& tag) const;
};
typedef boost::shared_ptr<xPLMessage> xPLMessagePtr;
+
+std::ostream& operator<<(std::ostream& os, const xPLMessage& msg);
Modified: xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt 2011-12-19 21:35:14 UTC (rev 601)
@@ -23,11 +23,11 @@
file(GLOB_RECURSE UnitTests_sources *.cpp)
#set(UnitTest_tsrc ../src/devicemanager.cpp ../src/xplcache.cpp ../src/xplhandler.cpp ../src/xplmessagequeue.cpp)
-set(UnitTest_tsrc ../src/devicemanager.cpp)
+set(UnitTest_tsrc ../src/devicemanager.cpp ../src/xplmessage.cpp)
add_executable(test_runner ${UnitTests_sources} ${UnitTest_tsrc})
-include_directories(../src)
+include_directories(../src /usr/local/include)
enable_testing()
@@ -38,7 +38,7 @@
#message(STATUS "LIBRARIES=${LIBS}")
#message(STATUS "SOURCE=${SOURCES}")
#target_link_libraries(xPLHAL ${Boost_LIBRARIES} -dynamic xPL pthread -static)
-target_link_libraries(test_runner ${LIBS})
+target_link_libraries(test_runner ${LIBS} mockpp)
add_test(UnitTests test_runner)
Added: xPLHAL/branches/thomas_s_dev/test/mock_xplhandler.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/mock_xplhandler.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/test/mock_xplhandler.h 2011-12-19 21:35:14 UTC (rev 601)
@@ -0,0 +1,62 @@
+#include <mockpp/visiting/CountedVisitableMethod.h>
+#include "i_xplhandler.h"
+
+using namespace mockpp;
+
+class MockXplHandler : public IxPLHandler, public VisitableMockObject
+{
+ public:
+ MockXplHandler()
+ : VisitableMockObject("MockXplHandler", 0)
+ , sendBroadcastMessage_mocker("sendBroadcastMessage", this)
+ , sendMessage_mocker("sendMessage", this)
+ , sendMessage2_mocker("sendMessage", this)
+ {}
+
+ void sendBroadcastMessage( const std::string& msgClass, const std::string& msgType, const xPLMessage::namedValueList& namedValues ) const
+ {
+#if 0
+ std::cout << "sendBroadcastMessage(";
+ std::cout << msgClass << ",";
+ std::cout << msgType << ",";
+ std::cout << std::endl;
+#endif
+ sendBroadcastMessage_mocker.forward(msgClass, msgType);
+ }
+// VisitableMockMethod<void, std::string, xPLMessage::namedValueList> sendBroadcastMessage_mocker;
+ VisitableMockMethod<void, std::string, std::string> sendBroadcastMessage_mocker;
+
+ /** \brief Send a directed message to the xPL network. */
+ void sendMessage( const xPL_MessageType type, const std::string& tgtVendor, const std::string& tgtDeviceID,
+ const std::string& tgtInstanceID, const std::string& msgClass, const std::string& msgType,
+ const xPLMessage::namedValueList& namedValues ) const
+ {
+#if 0
+ std::cout << "sendMessage(";
+ std::cout << type << ",";
+ std::cout << tgtVendor << "-" << tgtDeviceID << "." << tgtInstanceID << ",";
+ std::cout << msgClass << "," << msgType;
+ std::cout << std::endl;
+#endif
+ sendMessage_mocker.forward(type, tgtVendor, tgtDeviceID, tgtInstanceID, msgClass, msgType);
+ }
+// VisitableMockMethod<void, std::string, std::string, std::string, std::string, std::string, xPLMessage::namedValueList> sendMessage_mocker;
+ VisitableMockMethod<void, xPL_MessageType, std::string, std::string, std::string, std::string, std::string> sendMessage_mocker;
+
+ /** \brief Send a directed message to the xPL network. */
+ void sendMessage( const xPL_MessageType type, const std::string& VDI,
+ const std::string& msgClass, const std::string& msgType, const xPLMessage::namedValueList& namedValues ) const
+ {
+#if 0
+ std::cout << "sendMessage2(";
+ std::cout << type << ",";
+ std::cout << VDI << ",";
+ std::cout << msgClass << "," << msgType;
+ std::cout << std::endl;
+#endif
+ sendMessage2_mocker.forward(type, VDI, msgClass, msgType);
+ }
+// VisitableMockMethod<void, std::string, std::string, std::string, xPLMessage::namedValueList> sendMessage2_mocker;
+ VisitableMockMethod<void, xPL_MessageType, std::string, std::string, std::string> sendMessage2_mocker;
+};
+
Modified: xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp 2011-12-19 17:29:18 UTC (rev 600)
+++ xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp 2011-12-19 21:35:14 UTC (rev 601)
@@ -1,10 +1,13 @@
#include "../src/devicemanager.h"
#define BOOST_TEST_MODULE "DeviceManager"
#include <boost/test/unit_test.hpp>
+//#include "mock_xplhandler.h"
//#include "xplcache.h"
#include "devicemanager.h"
+#include <boost/regex.hpp>
+
// load globas and give them their space to live
//#include "globals.h"
@@ -17,6...
[truncated message content] |
|
From: <tho...@us...> - 2012-02-11 20:39:56
|
Revision: 696
http://openautomation.svn.sourceforge.net/openautomation/?rev=696&view=rev
Author: thomas_s
Date: 2012-02-11 20:39:47 +0000 (Sat, 11 Feb 2012)
Log Message:
-----------
added determinator object with basic parsing of xml determinators
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
Added Paths:
-----------
xPLHAL/branches/thomas_s_dev/src/determinator.cpp
xPLHAL/branches/thomas_s_dev/src/determinator.h
xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp
xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
xPLHAL/branches/thomas_s_dev/src/pugiconfig.hpp
xPLHAL/branches/thomas_s_dev/src/pugixml.cpp
xPLHAL/branches/thomas_s_dev/src/pugixml.hpp
xPLHAL/branches/thomas_s_dev/test/determinator1.xml
xPLHAL/branches/thomas_s_dev/test/determinator2.xml
xPLHAL/branches/thomas_s_dev/test/determinatorDesc.xml
xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-02-11 19:40:21 UTC (rev 695)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-02-11 20:39:47 UTC (rev 696)
@@ -17,11 +17,12 @@
project(xPLHAL)
cmake_minimum_required(VERSION 2.6)
-#set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
-set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -std=c++0x")
+#set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp
xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp
- xhcp.cpp xplmessage.cpp recurring_timer.cpp main.cpp)
+ xhcp.cpp xplmessage.cpp recurring_timer.cpp main.cpp pugixml.cpp
+ determinatoritems.cpp determinator.cpp)
add_executable(xPLHAL ${xPLHAL_SRCS})
#message(STATUS "Boost_LIBRARIES=${Boost_LIBRARIES}")
Added: xPLHAL/branches/thomas_s_dev/src/determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-02-11 20:39:47 UTC (rev 696)
@@ -0,0 +1,111 @@
+#include "determinator.h"
+#include <iostream>
+#include <cxxabi.h>
+#include <typeinfo>
+#include <memory>
+
+using std::string;
+using std::vector;
+using std::cerr;
+using std::endl;
+
+void Determinator::printDeterminator() const
+{
+ cerr << "Determinator '" << name << "'";
+ cerr << "\n guid: " << guid;
+ cerr << "\n name: " << name;
+ cerr << "\n description: " << description;
+ cerr << "\n enabled: " << enabled;
+
+ cerr << "\n Inputs:\n";
+ for (auto input : inputs) {
+ cerr << " " << input.second->toString() << endl;
+ }
+
+ cerr << "\n Outputs:\n";
+ for (auto output : outputs) {
+ cerr << " " << output.second->toString() << endl;
+ }
+
+ cerr << endl;
+}
+
+DeterminatorXmlParser::DeterminatorXmlParser(const string& filename)
+{
+ registerCondition(BaseDeterminatorItemConstPtr(new XplCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new GlobalCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new GlobalChanged));
+ registerCondition(BaseDeterminatorItemConstPtr(new DayCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new TimeCondition));
+
+ registerAction(BaseDeterminatorItemConstPtr(new LogAction));
+
+ pugi::xml_parse_result result = m_doc.load_file(filename.c_str());
+ cerr << "Load result: " << result.description() << "\n";
+}
+
+void DeterminatorXmlParser::registerCondition(BaseDeterminatorItemConstPtr condition)
+{
+ m_conditionmap[condition->item_name] = condition;
+}
+
+void DeterminatorXmlParser::registerAction(BaseDeterminatorItemConstPtr action)
+{
+ m_actionmap[action->item_name] = action;
+}
+
+Determinator DeterminatorXmlParser::parse()
+{
+ try {
+ pugi::xml_node base = getNode(m_doc, "xplDeterminator");
+ pugi::xml_node base_d = getNode(base, "determinator");
+
+ bool isGroup = base_d.attribute("isGroup").value() == "Y";
+
+ if (isGroup == false) {
+ Determinator d;
+ d.guid = base_d.attribute("guid").value();
+ d.name = base_d.attribute("name").value();
+ d.description = base_d.attribute("description").value();
+ d.enabled = base_d.attribute("guid").value() == "Y";
+
+ pugi::xml_node input = base_d.child("input");
+ pugi::xml_node output = base_d.child("output");
+
+ for(auto condition : m_conditionmap) {
+ pugi::xml_node action_node = input.child(condition.first.c_str());
+ if (action_node) {
+ d.inputs.insert({condition.first, BaseDeterminatorItemPtr(condition.second->createNew(action_node))} );
+ }
+ }
+ for(auto action : m_actionmap) {
+ pugi::xml_node action_node = output.child(action.first.c_str());
+ if (action_node) {
+ d.outputs.insert({action.first, BaseDeterminatorItemPtr(action.second->createNew(action_node))} );
+ }
+ }
+
+ d.printDeterminator();
+ return d;
+ }
+
+ }
+ catch(const std::exception& e) {
+ int status;
+ char* realname = abi::__cxa_demangle(typeid(e).name(), 0, 0, &status);
+ cerr << "Exception: " << realname << " => " << e.what() << endl;
+ throw;
+ }
+
+}
+
+
+pugi::xml_node DeterminatorXmlParser::getNode(const pugi::xml_node& base, const string& childname)
+{
+ pugi::xml_node node = base.child(childname.c_str());
+ if (!node) {
+ throw DeterminatorParseException("node '" + childname +"' not found");
+ }
+ return node;
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/determinator.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-02-11 20:39:47 UTC (rev 696)
@@ -0,0 +1,41 @@
+#pragma once
+#include "pugixml.hpp"
+#include "determinatoritems.h"
+#include <string>
+#include <vector>
+#include <map>
+
+class Determinator
+{
+ public:
+ enum class match_type { ALL, ANY };
+
+ void printDeterminator() const;
+
+ std::string guid;
+ std::string name;
+ std::string description;
+ bool enabled;
+ match_type input_match_type;
+
+ std::multimap<std::string, BaseDeterminatorItemPtr> inputs;
+ std::multimap<std::string, BaseDeterminatorItemPtr> outputs;
+};
+
+class DeterminatorXmlParser
+{
+ public:
+ DeterminatorXmlParser(const std::string& filename);
+
+ void registerCondition(BaseDeterminatorItemConstPtr condition);
+ void registerAction(BaseDeterminatorItemConstPtr action);
+ Determinator parse();
+
+ private:
+ pugi::xml_node getNode(const pugi::xml_node& base, const std::string& childname);
+
+ pugi::xml_document m_doc;
+ std::map<std::string, std::shared_ptr<const BaseDeterminatorItem>> m_conditionmap;
+ std::map<std::string, std::shared_ptr<const BaseDeterminatorItem>> m_actionmap;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp 2012-02-11 20:39:47 UTC (rev 696)
@@ -0,0 +1,277 @@
+#include "determinatoritems.h"
+#include <cxxabi.h>
+#include <iostream>
+#include <typeinfo>
+#include <iostream>
+
+using std::string;
+using std::vector;
+
+ConditionParseException::ConditionParseException(const string& text)
+:m_text(text)
+{
+}
+
+const char* ConditionParseException::what() const throw()
+{
+ return m_text.c_str();
+
+}
+
+DeterminatorParseException::DeterminatorParseException(const string& text)
+:m_text(text)
+{
+}
+
+const char* DeterminatorParseException::what() const throw()
+{
+ return m_text.c_str();
+}
+
+
+class ScopedXmlAttributeGetter
+{
+ public:
+ ScopedXmlAttributeGetter(const pugi::xml_node& basenode) :m_basenode(basenode) {}
+ string get(const string& attribute_name) const {
+ pugi::xml_attribute xml_attribute = m_basenode.attribute(attribute_name.c_str());
+ if (!xml_attribute) {
+ string error_text = string("In node '") + m_basenode.name() + "'";
+ error_text += " attribute '" + attribute_name + "' was not found";
+ throw ConditionParseException(error_text);
+ }
+ return xml_attribute.value();
+ }
+ private:
+ const pugi::xml_node& m_basenode;
+};
+
+BaseDeterminatorItem::BaseDeterminatorItem(const string& name)
+:item_name(name)
+{
+}
+
+BaseDeterminatorItem::BaseDeterminatorItem(const pugi::xml_node& basenode, const string& name)
+:item_name(name)
+{
+ ScopedXmlAttributeGetter a(basenode);
+ display_name = a.get("display_name");
+}
+
+/*
+ * Determinator Conditions
+ */
+
+XplCondition::XplCondition()
+:BaseDeterminatorItem("xplCondition")
+{
+}
+
+XplCondition::XplCondition(const pugi::xml_node& basenode)
+:BaseDeterminatorItem(basenode, "xplCondition")
+{
+ parseFromXml(basenode);
+}
+
+BaseDeterminatorItemPtr XplCondition::createNew(const pugi::xml_node& basenode) const
+{
+ return BaseDeterminatorItemPtr(new XplCondition(basenode));
+}
+
+void XplCondition::parseFromXml(const pugi::xml_node& basenode)
+{
+ ScopedXmlAttributeGetter helper(basenode);
+ msg_type = helper.get("msg_type");
+ source_vendor = helper.get("source_vendor");
+ source_device = helper.get("source_device");
+ source_instance = helper.get("source_instance");
+ target_vendor = helper.get("target_vendor");
+ target_device = helper.get("target_device");
+ target_instance = helper.get("target_instance");
+ schema_class = helper.get("schema_class");
+ schema_type = helper.get("schema_type");
+
+ for(const auto node : basenode) {
+ if (node.name() == string("param")) {
+ struct parameter p;
+ ScopedXmlAttributeGetter pa(node);
+ p.name = pa.get("name");
+ p.op = pa.get("operator");
+ p.value = pa.get("value");
+ parameter.push_back(p);
+ }
+ }
+}
+
+string XplCondition::toString() const
+{
+ string ret = "xplCondition:";
+ ret += "\nmsg_type: " + msg_type;
+ ret += "\nsource_vendor: " + source_vendor;
+ ret += "\nsource_device: " + source_device;
+ ret += "\nsource_instance: " + source_instance;
+ ret += "\ntarget_vendor: " + target_vendor;
+ ret += "\ntarget_device: " + target_device;
+ ret += "\ntarget_instance: " + target_instance;
+ ret += "\nschema_class: " + schema_class;
+ ret += "\nschema_type: " + schema_type;
+ for (auto p : parameter) {
+ ret +="\nparameter: " + p.name + p.op + p.value;
+ }
+ return ret;
+}
+
+
+GlobalCondition::GlobalCondition()
+:BaseDeterminatorItem("globalCondition")
+{
+}
+
+GlobalCondition::GlobalCondition(const pugi::xml_node& basenode)
+:BaseDeterminatorItem(basenode, "globalCondition")
+{
+ parseFromXml(basenode);
+}
+
+BaseDeterminatorItemPtr GlobalCondition::createNew(const pugi::xml_node& basenode) const
+{
+ return BaseDeterminatorItemPtr(new GlobalCondition(basenode));
+}
+
+void GlobalCondition::parseFromXml(const pugi::xml_node& basenode)
+{
+ name = basenode.attribute("name").value();
+ op = basenode.attribute("operator").value();
+ value = basenode.attribute("value").value();
+}
+
+string GlobalCondition::toString() const
+{
+ string ret = item_name + ":";
+ ret += "\nname: " + name;
+ ret += "\noperator: " + op;
+ ret += "\nvalue: " + value;
+ return ret;
+}
+
+GlobalChanged::GlobalChanged()
+:BaseDeterminatorItem("globalChanged")
+{
+}
+
+GlobalChanged::GlobalChanged(const pugi::xml_node& basenode)
+:BaseDeterminatorItem(basenode, "globalChanged")
+{
+ parseFromXml(basenode);
+}
+
+BaseDeterminatorItemPtr GlobalChanged::createNew(const pugi::xml_node& basenode) const
+{
+ return BaseDeterminatorItemPtr(new GlobalChanged(basenode));
+}
+
+void GlobalChanged::parseFromXml(const pugi::xml_node& basenode)
+{
+ name = basenode.attribute("name").value();
+}
+
+string GlobalChanged::toString() const
+{
+ string ret = item_name + ":";
+ ret += "\nname: " + name;
+ return ret;
+}
+
+
+DayCondition::DayCondition()
+:BaseDeterminatorItem("dayCondition")
+{
+}
+
+DayCondition::DayCondition(const pugi::xml_node& basenode)
+:BaseDeterminatorItem(basenode, "dayCondition")
+{
+ parseFromXml(basenode);
+}
+
+BaseDeterminatorItemPtr DayCondition::createNew(const pugi::xml_node& basenode) const
+{
+ return BaseDeterminatorItemPtr(new DayCondition(basenode));
+}
+
+void DayCondition::parseFromXml(const pugi::xml_node& basenode)
+{
+ dow = basenode.attribute("dow").value();
+}
+
+string DayCondition::toString() const
+{
+ string ret = item_name + ":";
+ ret += "\ndow: " + dow;
+ return ret;
+}
+
+TimeCondition::TimeCondition()
+:BaseDeterminatorItem("timeCondition")
+{
+}
+
+TimeCondition::TimeCondition(const pugi::xml_node& basenode)
+ :BaseDeterminatorItem(basenode, "timeCondition")
+{
+ parseFromXml(basenode);
+}
+
+BaseDeterminatorItemPtr TimeCondition::createNew(const pugi::xml_node& basenode) const
+{
+ return BaseDeterminatorItemPtr(new TimeCondition(basenode));
+}
+
+void TimeCondition::parseFromXml(const pugi::xml_node& basenode)
+{
+ op = basenode.attribute("operator").value();
+ value = basenode.attribute("value").value();
+}
+
+string TimeCondition::toString() const
+{
+ string ret = item_name + ":";
+ ret += "\noperator: " + op;
+ ret += "\nvalue...: " + value;
+ return ret;
+}
+
+/*
+ * Determinator Actions
+ */
+
+LogAction::LogAction()
+:BaseDeterminatorItem("logAction")
+{
+}
+
+LogAction::LogAction(const pugi::xml_node& basenode)
+:BaseDeterminatorItem(basenode, "logAction")
+{
+ parseFromXml(basenode);
+}
+
+BaseDeterminatorItemPtr LogAction::createNew(const pugi::xml_node& basenode) const
+{
+ return BaseDeterminatorItemPtr(new LogAction(basenode));
+}
+
+void LogAction::parseFromXml(const pugi::xml_node& basenode)
+{
+ logText = basenode.attribute("logText").value();
+ executeOrder = basenode.attribute("executeOrder").value();
+}
+
+std::string LogAction::toString() const
+{
+ string ret = item_name + ":";
+ ret += "\nlogText.....: " + logText;
+ ret += "\nexecuteOrder: " + executeOrder;
+ return ret;
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinatoritems.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/determinatoritems.h 2012-02-11 20:39:47 UTC (rev 696)
@@ -0,0 +1,149 @@
+#pragma once
+#include "pugixml.hpp"
+#include <string>
+#include <vector>
+#include <memory>
+
+class ConditionParseException: public std::exception
+{
+ public:
+ ConditionParseException(const std::string& text);
+ virtual ~ConditionParseException() throw() {}
+ const char* what() const throw();
+ private:
+ std::string m_text;
+};
+
+class DeterminatorParseException: public std::exception
+{
+ public:
+ DeterminatorParseException(const std::string& text);
+ virtual ~DeterminatorParseException() throw() {}
+ const char* what() const throw();
+ private:
+ std::string m_text;
+};
+
+class BaseDeterminatorItem;
+typedef std::shared_ptr<BaseDeterminatorItem> BaseDeterminatorItemPtr;
+typedef std::shared_ptr<const BaseDeterminatorItem> BaseDeterminatorItemConstPtr;
+
+class BaseDeterminatorItem
+{
+ public:
+ BaseDeterminatorItem(const std::string& name);
+ BaseDeterminatorItem(const pugi::xml_node& basenode, const std::string& name);
+
+ virtual void parseFromXml(const pugi::xml_node& basenode) = 0;
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const = 0;
+ virtual std::string toString() const = 0;
+
+ std::string item_name;
+ std::string display_name;
+
+ //boost::signal2::signal<void ()> sigChanged;
+};
+
+class XplCondition: public BaseDeterminatorItem
+{
+ public:
+ XplCondition();
+ XplCondition(const pugi::xml_node& basenode);
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+
+ void parseFromXml(const pugi::xml_node& basenode);
+
+ std::string toString() const;
+
+ /* connect to signal of new xpl-message */
+ std::string msg_type;
+ std::string source_vendor;
+ std::string source_device;
+ std::string source_instance;
+ std::string target_vendor;
+ std::string target_device;
+ std::string target_instance;
+ std::string schema_class;
+ std::string schema_type;
+
+ struct parameter {
+ std::string name;
+ std::string op;
+ std::string value;
+ };
+
+ std::vector<struct parameter> parameter;
+};
+
+class GlobalCondition: public BaseDeterminatorItem
+{
+ public:
+ GlobalCondition();
+ GlobalCondition(const pugi::xml_node& basenode);
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+
+ void parseFromXml(const pugi::xml_node& basenode);
+
+ std::string toString() const;
+
+ std::string name;
+ std::string op;
+ std::string value;
+};
+
+class GlobalChanged: public BaseDeterminatorItem
+{
+ public:
+ /* connect to signal of changed global variable */
+ GlobalChanged();
+ GlobalChanged(const pugi::xml_node& basenode);
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string name;
+};
+
+class DayCondition: public BaseDeterminatorItem
+{
+ public:
+ DayCondition();
+ DayCondition(const pugi::xml_node& basenode);
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string dow;
+};
+
+class TimeCondition: public BaseDeterminatorItem
+{
+ public:
+ TimeCondition();
+ TimeCondition(const pugi::xml_node& basenode);
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string op;
+ std::string value;
+};
+
+class LogAction: public BaseDeterminatorItem
+{
+ public:
+ LogAction();
+ LogAction(const pugi::xml_node& basenode);
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string logText;
+ std::string executeOrder;
+};
Added: xPLHAL/branches/thomas_s_dev/src/pugiconfig.hpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/pugiconfig.hpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/pugiconfig.hpp 2012-02-11 20:39:47 UTC (rev 696)
@@ -0,0 +1,62 @@
+/**
+ * pugixml parser - version 1.0
+ * --------------------------------------------------------
+ * Copyright (C) 2006-2010, by Arseny Kapoulkine (ars...@gm...)
+ * Report bugs and download new versions at http://pugixml.org/
+ *
+ * This library is distributed under the MIT License. See notice at the end
+ * of this file.
+ *
+ * This work is based on the pugxml parser, which is:
+ * Copyright (C) 2003, by Kristen Wegner (kr...@ti...)
+ */
+
+#ifndef HEADER_PUGICONFIG_HPP
+#define HEADER_PUGICONFIG_HPP
+
+// Uncomment this to enable wchar_t mode
+// #define PUGIXML_WCHAR_MODE
+
+// Uncomment this to disable XPath
+#define PUGIXML_NO_XPATH
+
+// Uncomment this to disable STL
+// Note: you can't use XPath with PUGIXML_NO_STL
+// #define PUGIXML_NO_STL
+
+// Uncomment this to disable exceptions
+// Note: you can't use XPath with PUGIXML_NO_EXCEPTIONS
+// #define PUGIXML_NO_EXCEPTIONS
+
+// Set this to control attributes for public classes/functions, i.e.:
+// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
+// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
+// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
+// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
+
+#endif
+
+/**
+ * Copyright (c) 2006-2010 Arseny Kapoulkine
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
Added: xPLHAL/branches/thomas_s_dev/src/pugixml.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/pugixml.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/pugixml.cpp 2012-02-11 20:39:47 UTC (rev 696)
@@ -0,0 +1,9576 @@
+/**
+ * pugixml parser - version 1.0
+ * --------------------------------------------------------
+ * Copyright (C) 2006-2010, by Arseny Kapoulkine (ars...@gm...)
+ * Report bugs and download new versions at http://pugixml.org/
+ *
+ * This library is distributed under the MIT License. See notice at the end
+ * of this file.
+ *
+ * This work is based on the pugxml parser, which is:
+ * Copyright (C) 2003, by Kristen Wegner (kr...@ti...)
+ */
+
+#include "pugixml.hpp"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <wchar.h>
+
+#ifndef PUGIXML_NO_XPATH
+# include <math.h>
+# include <float.h>
+#endif
+
+#ifndef PUGIXML_NO_STL
+# include <istream>
+# include <ostream>
+# include <string>
+#endif
+
+// For placement new
+#include <new>
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4324) // structure was padded due to __declspec(align())
+# pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+# pragma warning(disable: 4702) // unreachable code
+# pragma warning(disable: 4996) // this function or variable may be unsafe
+#endif
+
+#ifdef __INTEL_COMPILER
+# pragma warning(disable: 177) // function was declared but never referenced
+# pragma warning(disable: 1478 1786) // function was declared "deprecated"
+#endif
+
+#ifdef __BORLANDC__
+# pragma warn -8008 // condition is always false
+# pragma warn -8066 // unreachable code
+#endif
+
+#ifdef __SNC__
+# pragma diag_suppress=178 // function was declared but never referenced
+# pragma diag_suppress=237 // controlling expression is constant
+#endif
+
+// uintptr_t
+#if !defined(_MSC_VER) || _MSC_VER >= 1600
+# include <stdint.h>
+#else
+# if _MSC_VER < 1300
+// No native uintptr_t in MSVC6
+typedef size_t uintptr_t;
+# endif
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef __int32 int32_t;
+#endif
+
+// Inlining controls
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+# define PUGIXML_NO_INLINE __declspec(noinline)
+#elif defined(__GNUC__)
+# define PUGIXML_NO_INLINE __attribute__((noinline))
+#else
+# define PUGIXML_NO_INLINE
+#endif
+
+// Simple static assertion
+#define STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; }
+
+// Digital Mars C++ bug workaround for passing char loaded from memory via stack
+#ifdef __DMC__
+# define DMC_VOLATILE volatile
+#else
+# define DMC_VOLATILE
+#endif
+
+using namespace pugi;
+
+// Memory allocation
+namespace
+{
+ void* default_allocate(size_t size)
+ {
+ return malloc(size);
+ }
+
+ void default_deallocate(void* ptr)
+ {
+ free(ptr);
+ }
+
+ allocation_function global_allocate = default_allocate;
+ deallocation_function global_deallocate = default_deallocate;
+}
+
+// String utilities
+namespace
+{
+ // Get string length
+ size_t strlength(const char_t* s)
+ {
+ assert(s);
+
+ #ifdef PUGIXML_WCHAR_MODE
+ return wcslen(s);
+ #else
+ return strlen(s);
+ #endif
+ }
+
+ // Compare two strings
+ bool strequal(const char_t* src, const char_t* dst)
+ {
+ assert(src && dst);
+
+ #ifdef PUGIXML_WCHAR_MODE
+ return wcscmp(src, dst) == 0;
+ #else
+ return strcmp(src, dst) == 0;
+ #endif
+ }
+
+ // Compare lhs with [rhs_begin, rhs_end)
+ bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count)
+ {
+ for (size_t i = 0; i < count; ++i)
+ if (lhs[i] != rhs[i])
+ return false;
+
+ return lhs[count] == 0;
+ }
+
+#ifdef PUGIXML_WCHAR_MODE
+ // Convert string to wide string, assuming all symbols are ASCII
+ void widen_ascii(wchar_t* dest, const char* source)
+ {
+ for (const char* i = source; *i; ++i) *dest++ = *i;
+ *dest = 0;
+ }
+#endif
+}
+
+#if !defined(PUGIXML_NO_STL) || !defined(PUGIXML_NO_XPATH)
+// auto_ptr-like buffer holder for exception recovery
+namespace
+{
+ struct buffer_holder
+ {
+ void* data;
+ void (*deleter)(void*);
+
+ buffer_holder(void* data, void (*deleter)(void*)): data(data), deleter(deleter)
+ {
+ }
+
+ ~buffer_holder()
+ {
+ if (data) deleter(data);
+ }
+
+ void* release()
+ {
+ void* result = data;
+ data = 0;
+ return result;
+ }
+ };
+}
+#endif
+
+namespace
+{
+ static const size_t xml_memory_page_size = 32768;
+
+ static const uintptr_t xml_memory_page_alignment = 32;
+ static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1);
+ static const uintptr_t xml_memory_page_name_allocated_mask = 16;
+ static const uintptr_t xml_memory_page_value_allocated_mask = 8;
+ static const uintptr_t xml_memory_page_type_mask = 7;
+
+ struct xml_allocator;
+
+ struct xml_memory_page
+ {
+ static xml_memory_page* construct(void* memory)
+ {
+ if (!memory) return 0; //$ redundant, left for performance
+
+ xml_memory_page* result = static_cast<xml_memory_page*>(memory);
+
+ result->allocator = 0;
+ result->memory = 0;
+ result->prev = 0;
+ result->next = 0;
+ result->busy_size = 0;
+ result->freed_size = 0;
+
+ return result;
+ }
+
+ xml_allocator* allocator;
+
+ void* memory;
+
+ xml_memory_page* prev;
+ xml_memory_page* next;
+
+ size_t busy_size;
+ size_t freed_size;
+
+ char data[1];
+ };
+
+ struct xml_memory_string_header
+ {
+ uint16_t page_offset; // offset from page->data
+ uint16_t full_size; // 0 if string occupies whole page
+ };
+
+ struct xml_allocator
+ {
+ xml_allocator(xml_memory_page* root): _root(root), _busy_size(root->busy_size)
+ {
+ }
+
+ xml_memory_page* allocate_page(size_t data_size)
+ {
+ size_t size = offsetof(xml_memory_page, data) + data_size;
+
+ // allocate block with some alignment, leaving memory for worst-case padding
+ void* memory = global_allocate(size + xml_memory_page_alignment);
+ if (!memory) return 0;
+
+ // align upwards to page boundary
+ void* page_memory = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1));
+
+ // prepare page structure
+ xml_memory_page* page = xml_memory_page::construct(page_memory);
+
+ page->memory = memory;
+ page->allocator = _root->allocator;
+
+ return page;
+ }
+
+ static void deallocate_page(xml_memory_page* page)
+ {
+ global_deallocate(page->memory);
+ }
+
+ void* allocate_memory_oob(size_t size, xml_memory_page*& out_page);
+
+ void* allocate_memory(size_t size, xml_memory_page*& out_page)
+ {
+ if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page);
+
+ void* buf = _root->data + _busy_size;
+
+ _busy_size += size;
+
+ out_page = _root;
+
+ return buf;
+ }
+
+ void deallocate_memory(void* ptr, size_t size, xml_memory_page* page)
+ {
+ if (page == _root) page->busy_size = _busy_size;
+
+ assert(ptr >= page->data && ptr < page->data + page->busy_size);
+ (void)!ptr;
+
+ page->freed_size += size;
+ assert(page->freed_size <= page->busy_size);
+
+ if (page->freed_size == page->busy_size)
+ {
+ if (page->next == 0)
+ {
+ assert(_root == page);
+
+ // top page freed, just reset sizes
+ page->busy_size = page->freed_size = 0;
+ _busy_size = 0;
+ }
+ else
+ {
+ assert(_root != page);
+ assert(page->prev);
+
+ // remove from the list
+ page->prev->next = page->next;
+ page->next->prev = page->prev;
+
+ // deallocate
+ deallocate_page(page);
+ }
+ }
+ }
+
+ char_t* allocate_str...
[truncated message content] |
|
From: <tho...@us...> - 2012-02-19 23:13:02
|
Revision: 710
http://openautomation.svn.sourceforge.net/openautomation/?rev=710&view=rev
Author: thomas_s
Date: 2012-02-19 23:12:54 +0000 (Sun, 19 Feb 2012)
Log Message:
-----------
- refactored determinatoritems
- added determinator actions (not fully implemented)
- refactored xplhandler to use asio for calling xPL_process_messages
WIP!
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/determinator.cpp
xPLHAL/branches/thomas_s_dev/src/determinator.h
xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp
xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
xPLHAL/branches/thomas_s_dev/src/globals.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp
xPLHAL/branches/thomas_s_dev/src/xplhandler.h
xPLHAL/branches/thomas_s_dev/src/xplmessagequeue.cpp
xPLHAL/branches/thomas_s_dev/src/xplmessagequeue.h
xPLHAL/branches/thomas_s_dev/test/determinator1.xml
xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp
Added Paths:
-----------
xPLHAL/branches/thomas_s_dev/src/actions/
xPLHAL/branches/thomas_s_dev/src/conditions/
xPLHAL/branches/thomas_s_dev/test/pugi.h
Modified: xPLHAL/branches/thomas_s_dev/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/CMakeLists.txt 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/CMakeLists.txt 2012-02-19 23:12:54 UTC (rev 710)
@@ -37,7 +37,7 @@
#set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
-find_package(Boost 1.38 COMPONENTS thread system filesystem date_time regex unit_test_framework)
+find_package(Boost 1.38 COMPONENTS thread system filesystem date_time regex unit_test_framework program_options)
find_package(xPL REQUIRED)
set(LIBS ${LIBS} ${Boost_LIBRARIES} ${xPL_LIBRARIES} pthread)
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-02-19 23:12:54 UTC (rev 710)
@@ -3,11 +3,14 @@
#include <cxxabi.h>
#include <typeinfo>
#include <memory>
+#include <functional>
using std::string;
using std::vector;
using std::cerr;
using std::endl;
+using std::thread;
+using std::bind;
void Determinator::printDeterminator() const
{
@@ -38,7 +41,8 @@
registerCondition(BaseDeterminatorItemConstPtr(new DayCondition));
registerCondition(BaseDeterminatorItemConstPtr(new TimeCondition));
- registerAction(BaseDeterminatorItemConstPtr(new LogAction));
+ registerAction(BaseDeterminatorItemConstPtr(new logAction));
+ registerAction(BaseDeterminatorItemConstPtr(new xplAction));
pugi::xml_parse_result result = m_doc.load_file(filename.c_str());
cerr << "Load result: " << result.description() << "\n";
@@ -70,6 +74,11 @@
d.enabled = base_d.attribute("guid").value() == "Y";
pugi::xml_node input = base_d.child("input");
+ d.input_match_type = Determinator::match_type::ALL;
+ if (input.attribute("match").value() == "any") {
+ d.input_match_type = Determinator::match_type::ANY;
+ }
+
pugi::xml_node output = base_d.child("output");
for(auto condition : m_conditionmap) {
@@ -81,7 +90,8 @@
for(auto action : m_actionmap) {
pugi::xml_node action_node = output.child(action.first.c_str());
if (action_node) {
- d.outputs.insert({action.first, BaseDeterminatorItemPtr(action.second->createNew(action_node))} );
+ BaseDeterminatorItemPtr actionObject(action.second->createNew(action_node));
+ d.outputs.insert({action.first, actionObject});
}
}
@@ -108,4 +118,59 @@
}
return node;
}
+
+Determinator::Determinator()
+{
+}
+Determinator::~Determinator()
+{
+ if (mExecuteThread) {
+ mExecuteThread->join();
+ }
+}
+
+bool Determinator::checkInputs() const
+{
+ for (auto input : inputs) {
+ bool match = input.second->match();
+ switch(input_match_type) {
+ case match_type::ALL: if (!match) return false;
+ case match_type::ANY: if (match) return true;
+ }
+ }
+ return (input_match_type == match_type::ALL);
+}
+
+void Determinator::executeOutputs() const
+{
+ std::multimap<string, BaseDeterminatorItemPtr> orderd_outputs;
+ for (auto output : outputs) {
+ string execOrder;
+ auto execOrderIter = output.second->attributes.find("executeOrder");
+ if (execOrderIter != output.second->attributes.end()) {
+ execOrder = execOrderIter->second;
+ }
+ orderd_outputs.insert({execOrder, output.second});
+ }
+
+ for (auto output : orderd_outputs) {
+ cerr << "execute output:" << output.second->display_name << endl;
+ output.second->execute();
+ }
+}
+
+/**
+ * Check if input conditions are met, then start a thread to execute actions
+ */
+void Determinator::execute()
+{
+ if (checkInputs()) {
+ if (mExecuteThread) {
+ mExecuteThread->join();
+ }
+ cerr << "determinator start thread" << endl;
+ mExecuteThread.reset(new thread(bind(&Determinator::executeOutputs, this)));
+ }
+}
+
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-02-19 23:12:54 UTC (rev 710)
@@ -4,14 +4,20 @@
#include <string>
#include <vector>
#include <map>
+#include <thread>
class Determinator
{
public:
+ explicit Determinator();
+ virtual ~Determinator();
+
enum class match_type { ALL, ANY };
void printDeterminator() const;
+ void execute();
+
std::string guid;
std::string name;
std::string description;
@@ -20,6 +26,12 @@
std::multimap<std::string, BaseDeterminatorItemPtr> inputs;
std::multimap<std::string, BaseDeterminatorItemPtr> outputs;
+
+ private:
+ bool checkInputs() const;
+ void executeOutputs() const;
+
+ std::unique_ptr<std::thread> mExecuteThread;
};
class DeterminatorXmlParser
Modified: xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp 2012-02-19 23:12:54 UTC (rev 710)
@@ -3,21 +3,12 @@
#include <iostream>
#include <typeinfo>
#include <iostream>
+#include "log.h"
using std::string;
using std::vector;
+using std::map;
-ConditionParseException::ConditionParseException(const string& text)
-:m_text(text)
-{
-}
-
-const char* ConditionParseException::what() const throw()
-{
- return m_text.c_str();
-
-}
-
DeterminatorParseException::DeterminatorParseException(const string& text)
:m_text(text)
{
@@ -32,18 +23,21 @@
class ScopedXmlAttributeGetter
{
public:
- ScopedXmlAttributeGetter(const pugi::xml_node& basenode) :m_basenode(basenode) {}
+ ScopedXmlAttributeGetter(const pugi::xml_node& basenode, map<string, string> &attributemap)
+ :m_basenode(basenode),m_attributemap(attributemap) {}
string get(const string& attribute_name) const {
pugi::xml_attribute xml_attribute = m_basenode.attribute(attribute_name.c_str());
if (!xml_attribute) {
string error_text = string("In node '") + m_basenode.name() + "'";
error_text += " attribute '" + attribute_name + "' was not found";
- throw ConditionParseException(error_text);
+ throw DeterminatorParseException(error_text);
}
+ m_attributemap.insert({attribute_name, xml_attribute.value()});
return xml_attribute.value();
}
private:
const pugi::xml_node& m_basenode;
+ map<string, string> &m_attributemap;
};
BaseDeterminatorItem::BaseDeterminatorItem(const string& name)
@@ -54,10 +48,19 @@
BaseDeterminatorItem::BaseDeterminatorItem(const pugi::xml_node& basenode, const string& name)
:item_name(name)
{
- ScopedXmlAttributeGetter a(basenode);
+ ScopedXmlAttributeGetter a(basenode, attributes);
display_name = a.get("display_name");
}
+
+bool BaseDeterminatorItem::match() const
+{
+ return true;
+}
+void BaseDeterminatorItem::execute() const
+{
+}
+
/*
* Determinator Conditions
*/
@@ -80,7 +83,7 @@
void XplCondition::parseFromXml(const pugi::xml_node& basenode)
{
- ScopedXmlAttributeGetter helper(basenode);
+ ScopedXmlAttributeGetter helper(basenode, attributes);
msg_type = helper.get("msg_type");
source_vendor = helper.get("source_vendor");
source_device = helper.get("source_device");
@@ -94,7 +97,7 @@
for(const auto node : basenode) {
if (node.name() == string("param")) {
struct parameter p;
- ScopedXmlAttributeGetter pa(node);
+ ScopedXmlAttributeGetter pa(node, attributes);
p.name = pa.get("name");
p.op = pa.get("operator");
p.value = pa.get("value");
@@ -120,8 +123,7 @@
}
return ret;
}
-
-
+
GlobalCondition::GlobalCondition()
:BaseDeterminatorItem("globalCondition")
{
@@ -140,9 +142,10 @@
void GlobalCondition::parseFromXml(const pugi::xml_node& basenode)
{
- name = basenode.attribute("name").value();
- op = basenode.attribute("operator").value();
- value = basenode.attribute("value").value();
+ ScopedXmlAttributeGetter helper(basenode, attributes);
+ name = helper.get("name");
+ op = helper.get("operator");
+ value = helper.get("value");
}
string GlobalCondition::toString() const
@@ -172,7 +175,8 @@
void GlobalChanged::parseFromXml(const pugi::xml_node& basenode)
{
- name = basenode.attribute("name").value();
+ ScopedXmlAttributeGetter helper(basenode, attributes);
+ name = helper.get("name");
}
string GlobalChanged::toString() const
@@ -201,7 +205,8 @@
void DayCondition::parseFromXml(const pugi::xml_node& basenode)
{
- dow = basenode.attribute("dow").value();
+ ScopedXmlAttributeGetter helper(basenode, attributes);
+ dow = helper.get("dow");
}
string DayCondition::toString() const
@@ -229,8 +234,9 @@
void TimeCondition::parseFromXml(const pugi::xml_node& basenode)
{
- op = basenode.attribute("operator").value();
- value = basenode.attribute("value").value();
+ ScopedXmlAttributeGetter helper(basenode, attributes);
+ op = helper.get("operator");
+ value = helper.get("value");
}
string TimeCondition::toString() const
@@ -245,33 +251,54 @@
* Determinator Actions
*/
-LogAction::LogAction()
-:BaseDeterminatorItem("logAction")
+void logAction::parseFromXml(const pugi::xml_node& basenode)
{
+ ScopedXmlAttributeGetter helper(basenode, attributes);
+ logText = helper.get("logText");
+ executeOrder = helper.get("executeOrder");
}
-LogAction::LogAction(const pugi::xml_node& basenode)
-:BaseDeterminatorItem(basenode, "logAction")
+std::string logAction::toString() const
{
- parseFromXml(basenode);
+ string ret = item_name + ":";
+ ret += "\nlogText.....: " + logText;
+ ret += "\nexecuteOrder: " + executeOrder;
+ return ret;
}
-BaseDeterminatorItemPtr LogAction::createNew(const pugi::xml_node& basenode) const
+void logAction::execute() const
{
- return BaseDeterminatorItemPtr(new LogAction(basenode));
+ writeLog(logText, logLevel::debug);
}
-void LogAction::parseFromXml(const pugi::xml_node& basenode)
+//-----
+
+void xplAction::parseFromXml(const pugi::xml_node& basenode)
{
- logText = basenode.attribute("logText").value();
- executeOrder = basenode.attribute("executeOrder").value();
+ ScopedXmlAttributeGetter helper(basenode, attributes);
+ executeOrder = helper.get("executeOrder");
+ msgType = helper.get("msgType");
+ msgTarget = helper.get("msgTarget");
+ msgSchema = helper.get("msgSchema");
+
+ for(const auto node : basenode) {
+ if (node.name() == string("xplActionParam")) {
+ string expression = node.attribute("expression").value();
+ }
+ }
}
-std::string LogAction::toString() const
+std::string xplAction::toString() const
{
string ret = item_name + ":";
- ret += "\nlogText.....: " + logText;
ret += "\nexecuteOrder: " + executeOrder;
+ ret += "\nmsgType.....: " + msgType;
+ ret += "\nmsgTarget...: " + msgTarget;
+ ret += "\nmsgSchema...: " + msgSchema;
return ret;
}
+void xplAction::execute() const
+{
+}
+
Modified: xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinatoritems.h 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/determinatoritems.h 2012-02-19 23:12:54 UTC (rev 710)
@@ -3,17 +3,8 @@
#include <string>
#include <vector>
#include <memory>
+#include <map>
-class ConditionParseException: public std::exception
-{
- public:
- ConditionParseException(const std::string& text);
- virtual ~ConditionParseException() throw() {}
- const char* what() const throw();
- private:
- std::string m_text;
-};
-
class DeterminatorParseException: public std::exception
{
public:
@@ -37,13 +28,40 @@
virtual void parseFromXml(const pugi::xml_node& basenode) = 0;
virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const = 0;
virtual std::string toString() const = 0;
+ virtual bool match() const;
+ virtual void execute() const;
std::string item_name;
std::string display_name;
+ std::map<std::string, std::string> attributes;
+
//boost::signal2::signal<void ()> sigChanged;
};
+template<typename T>
+class DeterminatorAction: public BaseDeterminatorItem
+{
+ public:
+ DeterminatorAction() :BaseDeterminatorItem(typeid(T).name()) { }
+ DeterminatorAction(const pugi::xml_node& basenode)
+ :BaseDeterminatorItem(basenode, std::string(typeid(T).name())) {
+ executeOrder = basenode.attribute("executeOrder").value();
+ attributes["executeOrder"] = executeOrder;
+ }
+
+ BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const {
+ return BaseDeterminatorItemPtr(new T(basenode));
+ }
+
+ std::string executeOrder;
+};
+
+
+/*
+ * Conditions
+ */
+
class XplCondition: public BaseDeterminatorItem
{
public:
@@ -134,16 +152,128 @@
std::string value;
};
-class LogAction: public BaseDeterminatorItem
+/*
+ * Actions
+ */
+
+class logAction: public DeterminatorAction<logAction>
{
public:
- LogAction();
- LogAction(const pugi::xml_node& basenode);
+ logAction() {}
+ logAction(const pugi::xml_node& basenode) : DeterminatorAction(basenode) {
+ parseFromXml(basenode);
+ }
- virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void execute() const;
void parseFromXml(const pugi::xml_node& basenode);
std::string toString() const;
std::string logText;
std::string executeOrder;
};
+
+class xplAction: public DeterminatorAction<xplAction>
+{
+ public:
+ xplAction() {}
+ xplAction(const pugi::xml_node& basenode) : DeterminatorAction(basenode) {
+ parseFromXml(basenode);
+ }
+
+ void execute() const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string msgType;
+ std::string msgTarget;
+ std::string msgSchema;
+ std::multimap<std::string, std::string> actionParams;
+};
+
+class globalAction: public DeterminatorAction<globalAction>
+{
+ public:
+ globalAction();
+ globalAction(const pugi::xml_node& basenode);
+ void execute() const;
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string name;
+ std::string value;
+};
+
+class delayAction: public DeterminatorAction<delayAction>
+{
+ public:
+ delayAction();
+ delayAction(const pugi::xml_node& basenode);
+ void execute() const;
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string delaySeconds;
+};
+
+class stopAction: public DeterminatorAction<stopAction>
+{
+ public:
+ stopAction();
+ stopAction(const pugi::xml_node& basenode);
+ void execute() const;
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+};
+
+class suspendAction: public DeterminatorAction<suspendAction>
+{
+ public:
+ suspendAction();
+ suspendAction(const pugi::xml_node& basenode);
+ void execute() const;
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string suspendMinutes;
+ std::string suspendTime;
+ std::string suspendRandomise;
+};
+
+class execRuleAction: public DeterminatorAction<execRuleAction>
+{
+ public:
+ execRuleAction();
+ execRuleAction(const pugi::xml_node& basenode);
+ void execute() const;
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string ruleName;
+};
+
+class runScriptAction: public DeterminatorAction<runScriptAction>
+{
+ public:
+ runScriptAction();
+ runScriptAction(const pugi::xml_node& basenode);
+ void execute() const;
+
+ virtual BaseDeterminatorItemPtr createNew(const pugi::xml_node& basenode) const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string scriptName;
+ std::string parameter;
+};
+
Modified: xPLHAL/branches/thomas_s_dev/src/globals.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/globals.h 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/globals.h 2012-02-19 23:12:54 UTC (rev 710)
@@ -31,9 +31,6 @@
class xPLHandler;
extern xPLHandler *xPL;
-class xPLMessageQueueClass;
-extern xPLMessageQueueClass *xPLMessageQueue;
-
/** The working directories */
extern boost::filesystem::path xPLHalRootFolder;
extern boost::filesystem::path DataFileFolder;
Modified: xPLHAL/branches/thomas_s_dev/src/main.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-02-19 23:12:54 UTC (rev 710)
@@ -16,17 +16,26 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <signal.h>
+#include <boost/program_options.hpp>
#include "log.h"
-#include "xplcache.h"
#include "devicemanager.h"
#include "xhcp.h"
#include "recurring_timer.h"
+#include "xplhandler.h"
+#include "xplcache.h"
// load globas and give them their space to live
#include "globals.h"
using boost::filesystem::path;
using boost::filesystem::initial_path;
+using boost::program_options::options_description;
+using boost::program_options::variables_map;
+using boost::program_options::store;
+using boost::program_options::parse_command_line;
+using boost::program_options::notify;
+using std::cout;
+using std::endl;
path xPLHalRootFolder;
path DataFileFolder;
@@ -35,7 +44,6 @@
xPLCacheClass *xPLCache;
xPLHandler *xPL;
-xPLMessageQueueClass *xPLMessageQueue;
static boost::asio::io_service* g_ioservice = nullptr;
@@ -43,22 +51,20 @@
{
public:
XplHalApplication()
- :mXplMessageQueue(new xPLMessageQueueClass)
- ,mXplCache(new xPLCacheClass)
+ :mXplCache(new xPLCacheClass)
,mDeviceManager(mXplCache)
,mXHCPServer(new XHCPServer(m_ioservice, &mDeviceManager))
- ,mXpl(new xPLHandler( boost::asio::ip::host_name() ))
+ ,mXpl(new xPLHandler(m_ioservice, boost::asio::ip::host_name() ))
,mTimerListAllObjects(m_ioservice, boost::posix_time::seconds(60), true)
,mTimerFlushExpiredEntries(m_ioservice, boost::posix_time::minutes(5), true)
{
- mDeviceManager.m_sigSendXplMessage.connect(boost::bind(&xPLMessageQueueClass::add, mXplMessageQueue, _1));
+ mDeviceManager.m_sigSendXplMessage.connect(boost::bind(&xPLHandler::sendMessage, mXpl, _1));
mXpl->m_sigRceivedXplMessage.connect(boost::bind(&DeviceManager::processXplMessage, &mDeviceManager, _1));
installTimer();
/* set global variables */
xPLCache = mXplCache;
xPL = mXpl;
- xPLMessageQueue = mXplMessageQueue;
writeLog( "initialized", logLevel::all );
}
@@ -97,7 +103,7 @@
int exec()
{
// force everyone to send their configuration so that we start up to date...
- xPLMessageQueue->add(xPLMessagePtr( new xPLMessage(xPL_MESSAGE_COMMAND, "*", "config", "current", {{"command", "request"}}) ));
+ mXpl->sendMessage(xPLMessagePtr( new xPLMessage(xPL_MESSAGE_COMMAND, "*", "config", "current", {{"command", "request"}}) ));
writeLog( "started, run mainloop", logLevel::all );
m_ioservice.run();
@@ -113,7 +119,6 @@
private:
static boost::asio::io_service m_ioservice;
- xPLMessageQueueClass *mXplMessageQueue;
xPLCacheClass *mXplCache;
DeviceManager mDeviceManager;
XHCPServer *mXHCPServer;
@@ -146,6 +151,20 @@
//vendorFileFolder = DataFileFolder / "vendors";
//ConfigFileFolder = DataFileFolder / "configs";
+ options_description desc("Allowed options");
+ desc.add_options()
+ ("help", "help message")
+ ("datadir","location of data directory");
+
+ variables_map vm;
+ store(parse_command_line(argc, argv, desc), vm);
+ notify(vm);
+
+ if (vm.count("help")) {
+ cout << desc << endl;
+ return 1;
+ }
+
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
Modified: xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/xplhandler.cpp 2012-02-19 23:12:54 UTC (rev 710)
@@ -16,14 +16,15 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "xplhandler.h"
+#include "xplmessagequeue.h"
+
#include <boost/algorithm/string/replace.hpp>
using std::string;
#include "log.h"
-#include "xplhandler.h"
-#include "globals.h"
/** Handle a change to the logger service configuration */
/* static void configChangedHandler(xPL_ServicePtr theService, xPL_ObjectPtr userData) {
@@ -31,12 +32,14 @@
int xPLHandler::m_refcount = 0;
-xPLHandler::xPLHandler( const string& host_name)
+xPLHandler::xPLHandler(boost::asio::io_service& ioservice, const std::string& host_name)
: xPLService(0)
-, m_exit_thread(false)
, vendor( "CHRISM" )
, deviceID( "xplhalqt" )
, instanceID( host_name )
+, m_xplSocket(ioservice)
+, m_xplWriteSocket(ioservice)
+, mXplMessageQueue(new XplMessageQueue)
{
writeLog( "xPLHandler::xPLHandler( "+host_name+" )", logLevel::debug );
//xPL_setDebugging(TRUE);
@@ -54,7 +57,7 @@
writeLog("Unable to start xPL", logLevel::debug);
}
}
-
+
/* And a listener for all xPL messages */
xPL_addMessageListener( xpl_message_callback, this );
@@ -82,16 +85,17 @@
xPL_addServiceConfigChangedListener(loggerService, configChangedHandler, NULL);*/
//xPL_setServiceEnabled(loggerService, TRUE);
xPL_setServiceEnabled(xPLService, TRUE);
-
- m_thread = new boost::thread(boost::bind(&xPLHandler::run, this));
+
+ m_xplSocket.assign(boost::asio::ip::tcp::v4(), xPL_getFD());
+ m_xplWriteSocket.assign(boost::asio::ip::tcp::v4(), mXplMessageQueue->getFD());
+ startAsyncRead();
+ startAsyncWrite();
}
xPLHandler::~xPLHandler()
{
writeLog( "xPLHandler::~xPLHandler()", logLevel::debug );
- m_exit_thread = true;
- m_thread->join();
- delete m_thread;
+ m_xplSocket.close();
if (xPLService) {
xPL_releaseService(xPLService);
}
@@ -100,56 +104,30 @@
}
}
-void xPLHandler::run()
+void xPLHandler::sendBroadcastMessage( const string& msgClass, const string& msgType, const xPLMessage::namedValueList& namedValues )
{
- writeLog( "xPLHandler::run()", logLevel::debug );
- // writeLog( "xPLHandler::run() - ready", logLevel::debug );
-
- // Hand control over to xPLLib
- while( ! m_exit_thread )
- {
- // get exclusive access to xPLib
- //lock_guard locker( xPLLock );
-
- // send waiting messages
- while( xPL_MessagePtr theMessage = xPLMessageQueue->consume( xPLService ) )
- {
- writeLog("Found xPL message at " + lexical_cast<string>(theMessage)+ " to send...", logLevel::debug);
- if ( !xPL_sendMessage( theMessage ) )
- writeLog("Unable to send xPL message", logLevel::debug);
- else
- writeLog( "xPL Message sent...", logLevel::debug );
- }
-
- // handle messages - and return after 100 ms
- xPL_processMessages(100);
- }
-}
-
-void xPLHandler::sendBroadcastMessage( const string& msgClass, const string& msgType, const xPLMessage::namedValueList& namedValues ) const
-{
writeLog( "xPLHandler::sendBroadcastMessage( "+msgClass+", "+msgType+" )", logLevel::debug );
- xPLMessageQueue->add( xPLMessagePtr( new xPLMessage( xPL_MESSAGE_COMMAND, "*", "", "", msgClass, msgType, namedValues ) ) );
+ sendMessage( xPLMessagePtr( new xPLMessage( xPL_MESSAGE_COMMAND, "*", "", "", msgClass, msgType, namedValues ) ) );
}
void xPLHandler::sendMessage( const xPL_MessageType type, const string& tgtVendor, const string& tgtDeviceID,
const string& tgtInstanceID, const string& msgClass, const string& msgType,
- const xPLMessage::namedValueList& namedValues ) const
+ const xPLMessage::namedValueList& namedValues )
{
writeLog( "xPLHandler::sendMessage( "+lexical_cast<string>(type)+", "+tgtVendor+", "+tgtDeviceID+", "+tgtInstanceID+", "+msgClass+", "+msgType+" )", logLevel::debug );
- xPLMessageQueue->add( xPLMessagePtr( new xPLMessage( type, tgtVendor, tgtDeviceID, tgtInstanceID, msgClass, msgType, namedValues ) ) );
+ sendMessage( xPLMessagePtr( new xPLMessage( type, tgtVendor, tgtDeviceID, tgtInstanceID, msgClass, msgType, namedValues ) ) );
}
void xPLHandler::sendMessage( const xPL_MessageType type, const string& VDI,
const string& msgClass, const string& msgType,
- const xPLMessage::namedValueList& namedValues ) const
+ const xPLMessage::namedValueList& namedValues )
{
size_t marker1 = VDI.find( "-" );
size_t marker2 = VDI.find( "." );
string vendor = VDI.substr( 0, marker1 );
string device = VDI.substr( marker1+1, marker2 - (marker1+1) );
string instance = VDI.substr( marker2+1 );
- xPLMessageQueue->add( xPLMessagePtr( new xPLMessage( type, vendor, device, instance, msgClass, msgType, namedValues ) ) );
+ sendMessage( xPLMessagePtr( new xPLMessage( type, vendor, device, instance, msgClass, msgType, namedValues ) ) );
}
void xPLHandler::xpl_message_callback( xPL_MessagePtr theMessage, void *userValue )
@@ -196,3 +174,43 @@
m_sigRceivedXplMessage(msg);
}
+
+void xPLHandler::startAsyncRead()
+{
+ m_xplSocket.async_read_some(boost::asio::null_buffers(), boost::bind(&xPLHandler::handleReadableXplSocket, this, _1));
+}
+
+void xPLHandler::startAsyncWrite()
+{
+ m_xplWriteSocket.async_read_some(boost::asio::null_buffers(), boost::bind(&xPLHandler::handleReadableXplMessagequeue, this, _1));
+}
+
+void xPLHandler::handleReadableXplMessagequeue(boost::system::error_code ec)
+{
+ if (!ec) {
+ // send waiting messages
+ while( xPL_MessagePtr theMessage = mXplMessageQueue->consume( xPLService ) )
+ {
+ writeLog("Found xPL message at " + lexical_cast<string>(theMessage)+ " to send...", logLevel::debug);
+ if ( !xPL_sendMessage( theMessage ) )
+ writeLog("Unable to send xPL message", logLevel::debug);
+ else
+ writeLog( "xPL Message sent...", logLevel::debug );
+ }
+ startAsyncWrite();
+ }
+}
+
+void xPLHandler::handleReadableXplSocket(boost::system::error_code ec)
+{
+ if (!ec) {
+ // handle messages - and return
+ xPL_processMessages(0);
+ startAsyncRead();
+ }
+}
+
+void xPLHandler::sendMessage( const xPLMessagePtr& message )
+{
+ mXplMessageQueue->add(message);
+}
Modified: xPLHAL/branches/thomas_s_dev/src/xplhandler.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplhandler.h 2012-02-19 12:22:04 UTC (rev 709)
+++ xPLHAL/branches/thomas_s_dev/src/xplhandle...
[truncated message content] |
|
From: <tho...@us...> - 2012-03-04 18:48:39
|
Revision: 719
http://openautomation.svn.sourceforge.net/openautomation/?rev=719&view=rev
Author: thomas_s
Date: 2012-03-04 18:48:31 +0000 (Sun, 04 Mar 2012)
Log Message:
-----------
added DeterminatorManager class
moved Determinator-Items to subdirectories
refactored Determinator-Items (parsing and toString)
WIP
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/determinator.cpp
xPLHAL/branches/thomas_s_dev/src/determinator.h
xPLHAL/branches/thomas_s_dev/src/determinatoritems.cpp
xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/xplmessage.h
xPLHAL/branches/thomas_s_dev/src/xplmessagequeue.cpp
xPLHAL/branches/thomas_s_dev/src/xplmessagequeue.h
xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/test/determinator1.xml
xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp
xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
Added Paths:
-----------
xPLHAL/branches/thomas_s_dev/src/actions/delayAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/delayAction.h
xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.h
xPLHAL/branches/thomas_s_dev/src/actions/executeAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/executeAction.h
xPLHAL/branches/thomas_s_dev/src/actions/globalAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/globalAction.h
xPLHAL/branches/thomas_s_dev/src/actions/logAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/logAction.h
xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.h
xPLHAL/branches/thomas_s_dev/src/actions/stopAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/stopAction.h
xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.h
xPLHAL/branches/thomas_s_dev/src/actions/xplAction.cpp
xPLHAL/branches/thomas_s_dev/src/actions/xplAction.h
xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h
xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.h
xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.h
xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h
xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.h
xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp
xPLHAL/branches/thomas_s_dev/src/determinator_manager.h
xPLHAL/branches/thomas_s_dev/test/determinatorAll.xml
xPLHAL/branches/thomas_s_dev/test/test_determinator_manager.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-03-03 21:11:49 UTC (rev 718)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-03-04 18:48:31 UTC (rev 719)
@@ -17,13 +17,19 @@
project(xPLHAL)
cmake_minimum_required(VERSION 2.6)
-set(CMAKE_CXX_FLAGS "-g -std=c++0x")
-#set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
+file(GLOB_RECURSE Action_sources ./actions/*.cpp)
+file(GLOB_RECURSE Condition_sources ./conditions/*.cpp)
+
+#set(CMAKE_CXX_FLAGS "-g -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp
xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp
xhcp.cpp xplmessage.cpp recurring_timer.cpp main.cpp pugixml.cpp
- determinatoritems.cpp determinator.cpp)
+ determinatoritems.cpp determinator.cpp determinator_manager.cpp
+ ${Action_sources} ${Condition_sources})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
add_executable(xPLHAL ${xPLHAL_SRCS})
#message(STATUS "Boost_LIBRARIES=${Boost_LIBRARIES}")
#message(STATUS "LIBRARIES=${LIBS}")
Added: xPLHAL/branches/thomas_s_dev/src/actions/delayAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/delayAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/delayAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,17 @@
+#include "delayAction.h"
+
+using std::string;
+using std::vector;
+using std::map;
+
+delayAction::delayAction(const pugi::xml_node& basenode)
+{
+ attributes["delay_seconds"];
+ parseFromXml(basenode);
+}
+
+void delayAction::execute() const
+{
+ sleep(atoi(getAttribute("delaySeconds").c_str()));
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/delayAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/delayAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/delayAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,11 @@
+#pragma once
+#include "determinatoritems.h"
+
+class delayAction: public DeterminatorAction<delayAction>
+{
+ public:
+ delayAction() {}
+ delayAction(const pugi::xml_node& basenode);
+
+ void execute() const;
+};
Added: xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1 @@
+#include "execRuleAction.h"
Added: xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/execRuleAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,17 @@
+#pragma once
+#include "determinatoritems.h"
+
+class execRuleAction: public DeterminatorAction<execRuleAction>
+{
+ public:
+ execRuleAction() {}
+ execRuleAction(const pugi::xml_node& basenode) {
+ parseFromXml(basenode);
+ }
+ void execute() const;
+
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string ruleName;
+};
Added: xPLHAL/branches/thomas_s_dev/src/actions/executeAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/executeAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/executeAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1 @@
+#include "executeAction.h"
Added: xPLHAL/branches/thomas_s_dev/src/actions/executeAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/executeAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/executeAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,19 @@
+#pragma once
+#include "determinatoritems.h"
+
+class executeAction: public DeterminatorAction<executeAction>
+{
+ public:
+ executeAction() {}
+ executeAction(const pugi::xml_node& basenode) {
+ parseFromXml(basenode);
+ }
+ void execute() const;
+
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string program;
+ std::string parameters;
+ std::string wait;
+};
Added: xPLHAL/branches/thomas_s_dev/src/actions/globalAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/globalAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/globalAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,18 @@
+#include "globalAction.h"
+#include <iostream>
+
+using std::string;
+using std::cerr;
+
+globalAction::globalAction(const pugi::xml_node& basenode)
+{
+ attributes["name"];
+ attributes["value"];
+ parseFromXml(basenode);
+}
+
+void globalAction::execute() const
+{
+ std::cerr << "globalAction set " << getAttribute("name") << " to " << getAttribute("value") << "\n";
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/globalAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/globalAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/globalAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,12 @@
+#pragma once
+#include "determinatoritems.h"
+
+class globalAction: public DeterminatorAction<globalAction>
+{
+ public:
+ globalAction() {}
+ globalAction(const pugi::xml_node& basenode);
+
+ void execute() const;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/logAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/logAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/logAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,17 @@
+#include "logAction.h"
+#include "log.h"
+
+using std::string;
+
+logAction::logAction(const pugi::xml_node& basenode)
+: DeterminatorAction(basenode)
+{
+ attributes["logText"];
+ parseFromXml(basenode);
+}
+
+void logAction::execute() const
+{
+ writeLog(getAttribute("logText"), logLevel::debug);
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/logAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/logAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/logAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,12 @@
+#pragma once
+#include "determinatoritems.h"
+
+class logAction: public DeterminatorAction<logAction>
+{
+ public:
+ logAction() {}
+ logAction(const pugi::xml_node& basenode);
+
+ void execute() const;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,6 @@
+#include "runScriptAction.h"
+
+using std::string;
+using std::vector;
+using std::map;
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/runScriptAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,19 @@
+#pragma once
+#include "determinatoritems.h"
+
+class runScriptAction: public DeterminatorAction<runScriptAction>
+{
+ public:
+ runScriptAction() {}
+ runScriptAction(const pugi::xml_node& basenode) {
+ parseFromXml(basenode);
+ }
+ void execute() const;
+
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string scriptName;
+ std::string parameter;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/stopAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/stopAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/stopAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,15 @@
+#include "stopAction.h"
+
+using std::string;
+
+stopAction::stopAction(const pugi::xml_node& basenode)
+: DeterminatorAction(basenode)
+{
+ parseFromXml(basenode);
+}
+
+void stopAction::execute() const
+{
+ throw AbortDeterminatorExecutionException();
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/stopAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/stopAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/stopAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,11 @@
+#pragma once
+#include "determinatoritems.h"
+
+class stopAction: public DeterminatorAction<stopAction>
+{
+ public:
+ stopAction() {}
+ stopAction(const pugi::xml_node& basenode);
+ void execute() const;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,4 @@
+#include "suspendAction.h"
+
+using std::string;
+
Added: xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/suspendAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,19 @@
+#pragma once
+#include "determinatoritems.h"
+
+class suspendAction: public DeterminatorAction<suspendAction>
+{
+ public:
+ suspendAction() {}
+ suspendAction(const pugi::xml_node& basenode) {
+ parseFromXml(basenode);
+ }
+ void execute() const;
+
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::string suspendMinutes;
+ std::string suspendTime;
+ std::string suspendRandomise;
+};
Added: xPLHAL/branches/thomas_s_dev/src/actions/xplAction.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/xplAction.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/xplAction.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,37 @@
+#include "xplAction.h"
+
+using std::string;
+using std::shared_ptr;
+using boost::regex;
+
+xplAction::xplAction(const pugi::xml_node& basenode)
+: DeterminatorAction(basenode)
+{
+ attributes["msg_type"] = {shared_ptr<regex>(new regex(R"(^(stat|trig|cmnd)$)"))};
+ attributes["msg_target"] = {shared_ptr<regex>(new regex(R"(^(\*|.*-.*\..*)$)"))};
+ attributes["msg_schema"] = {shared_ptr<regex>(new regex(R"(^(.*\..*)$)"))};
+ parseFromXml(basenode);
+}
+
+void xplAction::parseFromXml(const pugi::xml_node& basenode)
+{
+ DeterminatorAction::parseFromXml(basenode);
+ for(const auto node : basenode) {
+ if (node.name() == string("xplActionParam")) {
+ actionParams.push_back(node.attribute("expression").value());
+ }
+ }
+}
+
+std::string xplAction::toString() const
+{
+ string ret = BaseDeterminatorItem::toString();
+ for (auto ap : actionParams) {
+ ret += "\nxplActionParam: " + ap;
+ }
+ return ret;
+}
+
+void xplAction::execute() const
+{
+}
Added: xPLHAL/branches/thomas_s_dev/src/actions/xplAction.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/actions/xplAction.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/actions/xplAction.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,16 @@
+#pragma once
+#include "determinatoritems.h"
+
+class xplAction: public DeterminatorAction<xplAction>
+{
+ public:
+ xplAction() {}
+ xplAction(const pugi::xml_node& basenode);
+
+ void execute() const;
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+
+ std::list<std::string> actionParams;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,10 @@
+#include "dayCondition.h"
+
+using std::string;
+
+dayCondition::dayCondition(const pugi::xml_node& basenode)
+{
+ attributes["dow"];
+ parseFromXml(basenode);
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,10 @@
+#pragma once
+#include "determinatoritems.h"
+
+class dayCondition: public DeterminatorCondition<dayCondition>
+{
+ public:
+ dayCondition() {}
+ dayCondition(const pugi::xml_node& basenode);
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,10 @@
+#include "globalChanged.h"
+
+using std::string;
+
+globalChanged::globalChanged(const pugi::xml_node& basenode)
+{
+ attributes["name"];
+ parseFromXml(basenode);
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/globalChanged.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,11 @@
+#pragma once
+#include "determinatoritems.h"
+
+class globalChanged: public DeterminatorCondition<globalChanged>
+{
+ public:
+ /* connect to signal of changed global variable */
+ globalChanged() {}
+ globalChanged(const pugi::xml_node& basenode);
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,13 @@
+#include "globalCondition.h"
+
+using std::string;
+using std::shared_ptr;
+using boost::regex;
+
+globalCondition::globalCondition(const pugi::xml_node& basenode)
+{
+ attributes["name"];
+ attributes["operator"] = {shared_ptr<regex>(new regex(R"(^(=|!=|<|>|<=|>=)$)"))};
+ attributes["value"];
+ parseFromXml(basenode);
+}
Added: xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/globalCondition.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,10 @@
+#pragma once
+#include "determinatoritems.h"
+
+class globalCondition: public DeterminatorCondition<globalCondition>
+{
+ public:
+ globalCondition() {}
+ globalCondition(const pugi::xml_node& basenode);
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,22 @@
+#include "timeCondition.h"
+#include <boost/regex.hpp>
+#include <memory>
+#include <map>
+
+using std::string;
+using std::shared_ptr;
+using std::map;
+using boost::regex;
+using boost::regex_match;
+
+timeCondition::timeCondition(const pugi::xml_node& basenode)
+{
+ attributes["operator"] = {shared_ptr<regex>(new regex(R"(^(=|!=|<|>|<=|>=)$)"))};
+ attributes["value"] = {shared_ptr<regex>(new regex(R"(^\d{1,2}:\d{1,2}$)"))};
+
+ parseFromXml(basenode);
+}
+
+bool timeCondition::match() const
+{
+}
Added: xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,12 @@
+#pragma once
+#include "determinatoritems.h"
+
+class timeCondition: public DeterminatorCondition<timeCondition>
+{
+ public:
+ timeCondition() {}
+ timeCondition(const pugi::xml_node& basenode);
+
+ virtual bool match() const;
+};
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,43 @@
+#include "xplCondition.h"
+#include <iostream>
+
+using std::string;
+using std::cerr;
+
+xplCondition::xplCondition(const pugi::xml_node& basenode)
+{
+ attributes["msg_type"];
+ attributes["source_vendor"];
+ attributes["source_device"];
+ attributes["source_instance"];
+ attributes["target_vendor"];
+ attributes["target_device"];
+ attributes["target_instance"];
+ attributes["schema_class"];
+ attributes["schema_type"];
+ parseFromXml(basenode);
+}
+
+void xplCondition::parseFromXml(const pugi::xml_node& basenode)
+{
+ BaseDeterminatorItem::parseFromXml(basenode);
+ for(const auto node : basenode) {
+ if (node.name() == string("param")) {
+ struct parameter p;
+ p.name = node.attribute("name").value();
+ p.op = node.attribute("operator").value();
+ p.value = node.attribute("value").value();
+ parameter.push_back(p);
+ }
+ }
+}
+
+string xplCondition::toString() const
+{
+ string ret = BaseDeterminatorItem::toString();
+ for (auto p : parameter) {
+ ret +="\nparameter: " + p.name + p.op + p.value;
+ }
+ return ret;
+}
+
Added: xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.h (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/xplCondition.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,22 @@
+#pragma once
+#include "determinatoritems.h"
+
+class xplCondition: public DeterminatorCondition<xplCondition>
+{
+ public:
+ xplCondition() {}
+ xplCondition(const pugi::xml_node& basenode);
+
+ void parseFromXml(const pugi::xml_node& basenode);
+ std::string toString() const;
+ /* connect to signal of new xpl-message */
+
+ struct parameter {
+ std::string name;
+ std::string op;
+ std::string value;
+ };
+
+ std::vector<struct parameter> parameter;
+};
+
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-03-03 21:11:49 UTC (rev 718)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -4,6 +4,19 @@
#include <typeinfo>
#include <memory>
#include <functional>
+#include <algorithm>
+#include <thread>
+#include <future>
+#include "conditions/xplCondition.h"
+#include "conditions/globalCondition.h"
+#include "conditions/globalChanged.h"
+#include "conditions/dayCondition.h"
+#include "conditions/timeCondition.h"
+#include "actions/logAction.h"
+#include "actions/xplAction.h"
+#include "actions/delayAction.h"
+#include "actions/globalAction.h"
+#include "actions/stopAction.h"
using std::string;
using std::vector;
@@ -35,17 +48,20 @@
DeterminatorXmlParser::DeterminatorXmlParser(const string& filename)
{
- registerCondition(BaseDeterminatorItemConstPtr(new XplCondition));
- registerCondition(BaseDeterminatorItemConstPtr(new GlobalCondition));
- registerCondition(BaseDeterminatorItemConstPtr(new GlobalChanged));
- registerCondition(BaseDeterminatorItemConstPtr(new DayCondition));
- registerCondition(BaseDeterminatorItemConstPtr(new TimeCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new xplCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new globalCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new globalChanged));
+ registerCondition(BaseDeterminatorItemConstPtr(new dayCondition));
+ registerCondition(BaseDeterminatorItemConstPtr(new timeCondition));
registerAction(BaseDeterminatorItemConstPtr(new logAction));
registerAction(BaseDeterminatorItemConstPtr(new xplAction));
+ registerAction(BaseDeterminatorItemConstPtr(new delayAction));
+ registerAction(BaseDeterminatorItemConstPtr(new globalAction));
+ registerAction(BaseDeterminatorItemConstPtr(new stopAction));
pugi::xml_parse_result result = m_doc.load_file(filename.c_str());
- cerr << "Load result: " << result.description() << "\n";
+// cerr << "Load result: " << result.description() << "\n";
}
void DeterminatorXmlParser::registerCondition(BaseDeterminatorItemConstPtr condition)
@@ -95,7 +111,7 @@
}
}
- d.printDeterminator();
+ //d.printDeterminator();
return d;
}
@@ -125,8 +141,8 @@
Determinator::~Determinator()
{
- if (mExecuteThread) {
- mExecuteThread->join();
+ if (!mExecFutures.empty()) {
+ mExecFutures[0].wait();
}
}
@@ -142,35 +158,42 @@
return (input_match_type == match_type::ALL);
}
-void Determinator::executeOutputs() const
+bool Determinator::executeOutputs() const
{
std::multimap<string, BaseDeterminatorItemPtr> orderd_outputs;
for (auto output : outputs) {
string execOrder;
auto execOrderIter = output.second->attributes.find("executeOrder");
if (execOrderIter != output.second->attributes.end()) {
- execOrder = execOrderIter->second;
+ execOrder = execOrderIter->second.value;
}
orderd_outputs.insert({execOrder, output.second});
}
- for (auto output : orderd_outputs) {
- cerr << "execute output:" << output.second->display_name << endl;
- output.second->execute();
+ try {
+ for (auto output : orderd_outputs) {
+ cerr << "execute output:" << output.second->getAttribute("display_name") << endl;
+ output.second->execute();
+ }
+ } catch (const AbortDeterminatorExecutionException &e) {
+ return false;
}
+ return true;
}
+
/**
* Check if input conditions are met, then start a thread to execute actions
*/
void Determinator::execute()
{
if (checkInputs()) {
- if (mExecuteThread) {
- mExecuteThread->join();
+ if (mExecFutures.empty() || mExecFutures[0].valid()) {
+ mExecFutures.erase(mExecFutures.begin(), mExecFutures.end());
+ cerr << "determinator start thread" << endl;
+ mExecFutures.push_back(std::async(std::launch::async, std::bind(&Determinator::executeOutputs, this)));
+ cerr << "determinator start thread" << endl;
}
- cerr << "determinator start thread" << endl;
- mExecuteThread.reset(new thread(bind(&Determinator::executeOutputs, this)));
}
}
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-03-03 21:11:49 UTC (rev 718)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-03-04 18:48:31 UTC (rev 719)
@@ -5,6 +5,7 @@
#include <vector>
#include <map>
#include <thread>
+#include <future>
class Determinator
{
@@ -29,11 +30,14 @@
private:
bool checkInputs() const;
- void executeOutputs() const;
-
- std::unique_ptr<std::thread> mExecuteThread;
+ bool executeOutputs() const;
+
+ std::vector<std::future<bool>> mExecFutures;
};
+typedef std::shared_ptr<Determinator> DeterminatorPtr;
+typedef std::shared_ptr<const Determinator> DeterminatorConstPtr;
+
class DeterminatorXmlParser
{
public:
Added: xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp (rev 0)
+++ xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp 2012-03-04 18:48:31 UTC (rev 719)
@@ -0,0 +1,58 @@
+#include "determinator_manager.h"
+#include "determinator.h"
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <iostream>
+
+using std::cout;
+using boost::filesystem::path;
+using boost::filesystem::exists;
+using boost::filesystem::filesystem_error;
+using boost::filesystem::is_regular_file;
+using boost::filesystem::is_directory;
+using boost::filesystem::directory_iterator;
+using boost::filesystem::ifstream;
+
+DeterminatorManager::DeterminatorManager(const std::string& determinatorDirectory)
+:mDeterminatorDirectory(determinatorDirectory)
+{
+}
+
+void DeterminatorManager::loadDeterminators()
+{
+ path p(mDeterminatorDirectory);
+ try {
+ if (exists(p)) {
+ if (is_regular_file(p)) {
+ cout << p << " is regular file\n";
+ }
+ else if (is_directory(p)) {
+ cout << p << " directory containing:\n";
+
+ for (auto item = directory_iterator(p); item != directory_iterator(); ++item) {
+ ifstream determinato...
[truncated message content] |
|
From: <tho...@us...> - 2012-03-04 22:03:01
|
Revision: 722
http://openautomation.svn.sourceforge.net/openautomation/?rev=722&view=rev
Author: thomas_s
Date: 2012-03-04 22:02:54 +0000 (Sun, 04 Mar 2012)
Log Message:
-----------
implemented dayCondition and timeCondition
implemented unittests for both classes
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h
xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp
xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h
xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp
xPLHAL/branches/thomas_s_dev/test/test_determinator_manager.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.cpp 2012-03-04 22:02:54 UTC (rev 722)
@@ -1,10 +1,34 @@
#include "dayCondition.h"
+#include <ctime>
+#include <chrono>
+#include <iostream>
using std::string;
+using std::chrono::time_point;
+using std::chrono::system_clock;
+using std::shared_ptr;
+using boost::regex;
+using std::cout;
+dayCondition::dayCondition(const BaseDeterminatorItem::attribute_t& attrlist)
+{
+ attributes = attrlist;
+}
+
dayCondition::dayCondition(const pugi::xml_node& basenode)
{
- attributes["dow"];
+ attributes["dow"] = {shared_ptr<regex>(new regex(R"(^[01]{7}$)"))};
parseFromXml(basenode);
}
+bool dayCondition::match() const
+{
+ std::time_t currentTime = std::time(0);
+ auto tm = std::localtime(¤tTime);
+ string dow_config = getAttribute("dow");
+
+ if (dow_config.length() == 7) {
+ return dow_config[tm->tm_wday] == '1';
+ }
+ return false;
+}
Modified: xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/dayCondition.h 2012-03-04 22:02:54 UTC (rev 722)
@@ -5,6 +5,9 @@
{
public:
dayCondition() {}
+ dayCondition(const BaseDeterminatorItem::attribute_t& attrlist);
dayCondition(const pugi::xml_node& basenode);
+
+ bool match() const;
};
Modified: xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.cpp 2012-03-04 22:02:54 UTC (rev 722)
@@ -1,22 +1,73 @@
#include "timeCondition.h"
-#include <boost/regex.hpp>
-#include <memory>
-#include <map>
+#include <chrono>
using std::string;
using std::shared_ptr;
-using std::map;
+using std::chrono::time_point;
+using std::chrono::duration;
+using std::chrono::system_clock;
using boost::regex;
using boost::regex_match;
+using boost::smatch;
+
+timeCondition::timeCondition(const BaseDeterminatorItem::attribute_t& attrlist, std::time_t fixTime)
+:mTestTime(fixTime)
+{
+ attributes["operator"] = {shared_ptr<regex>(new regex(R"(^(=|!=|<|>|<=|>=)$)"))};
+ attributes["value"] = {shared_ptr<regex>(new regex(R"(^(\d{1,2}):(\d{1,2})$)"))};
+
+ for (auto a : attrlist) {
+ attributes[a.first].value = a.second.value;
+ }
+
+ setCompareTime();
+}
+
timeCondition::timeCondition(const pugi::xml_node& basenode)
+:mTestTime(0)
{
attributes["operator"] = {shared_ptr<regex>(new regex(R"(^(=|!=|<|>|<=|>=)$)"))};
- attributes["value"] = {shared_ptr<regex>(new regex(R"(^\d{1,2}:\d{1,2}$)"))};
+ attributes["value"] = {shared_ptr<regex>(new regex(R"(^(\d{1,2}):(\d{1,2})$)"))};
parseFromXml(basenode);
+ setCompareTime();
}
+void timeCondition::setCompareTime()
+{
+ smatch res;
+
+ if (! regex_match(attributes["value"].value, res, *attributes["value"].re)) {
+ string error_text = "While creating timeCondition,";
+ error_text += " error getting value for attribute 'value': regex_match failed";
+ throw DeterminatorParseException(error_text);
+ }
+
+ mCompareHour = atoi(res.str(1).c_str());
+ mCompareMinute = atoi(res.str(2).c_str());
+}
+
bool timeCondition::match() const
{
+ /* for testing use mTestTime if != 0 */
+ std::time_t now = mTestTime ? mTestTime : std::time(0);
+ struct tm tm;
+ localtime_r(&now, &tm);
+
+ tm.tm_hour = mCompareHour;
+ tm.tm_min = mCompareMinute;
+
+ auto tp_now = system_clock::from_time_t(now);
+ auto tp_cmp = system_clock::from_time_t(std::mktime(&tm));
+
+ string op = getAttribute("operator");
+
+ if (op == "=") return tp_now == tp_cmp;
+ else if (op == "!=") return tp_now != tp_cmp;
+ else if (op == "<") return tp_now < tp_cmp;
+ else if (op == ">") return tp_now > tp_cmp;
+ else if (op == "<=") return tp_now <= tp_cmp;
+ else if (op == ">=") return tp_now >= tp_cmp;
+ return false;
}
Modified: xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/src/conditions/timeCondition.h 2012-03-04 22:02:54 UTC (rev 722)
@@ -1,12 +1,21 @@
#pragma once
#include "determinatoritems.h"
+#include <ctime>
class timeCondition: public DeterminatorCondition<timeCondition>
{
public:
- timeCondition() {}
+ timeCondition():mTestTime(0) {}
+ timeCondition(const BaseDeterminatorItem::attribute_t& attrlist, std::time_t fixTime);
timeCondition(const pugi::xml_node& basenode);
virtual bool match() const;
+
+ private:
+ void setCompareTime();
+
+ std::time_t mTestTime;
+ int mCompareHour;
+ int mCompareMinute;
};
Modified: xPLHAL/branches/thomas_s_dev/src/determinatoritems.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinatoritems.h 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/src/determinatoritems.h 2012-03-04 22:02:54 UTC (rev 722)
@@ -26,6 +26,14 @@
class BaseDeterminatorItem
{
public:
+ struct di_attribute {
+ std::shared_ptr<boost::regex> re;
+ std::string value;
+ };
+
+ typedef std::map<std::string, struct di_attribute> attribute_t;
+
+ public:
BaseDeterminatorItem(const std::string& name);
BaseDeterminatorItem(const pugi::xml_node& basenode, const std::string& name);
@@ -35,20 +43,11 @@
virtual void parseFromXml(const pugi::xml_node& basenode);
virtual bool match() const;
virtual void execute() const;
+ std::string getAttribute(const std::string& attrname) const;
- struct di_attribute {
- std::shared_ptr<boost::regex> re;
- std::string value;
- };
-
std::string item_name;
+ attribute_t attributes;
- std::string getAttribute(const std::string& attrname) const;
-
- std::map<std::string, struct di_attribute> attributes;
-
-
-
//boost::signal2::signal<void ()> sigChanged;
};
Modified: xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/test/test_determinator.cpp 2012-03-04 22:02:54 UTC (rev 722)
@@ -2,6 +2,8 @@
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <mockpp/visiting/CountedVisitableMethod.h>
+#include "../src/conditions/dayCondition.h"
+#include "../src/conditions/timeCondition.h"
using namespace mockpp;
@@ -137,4 +139,73 @@
d.execute();
}
+BOOST_AUTO_TEST_CASE( testdayConditon )
+{
+ dayCondition dc1({{"dow", {0, "1111111"}}});
+ BOOST_CHECK(dc1.match() == true);
+
+ dayCondition dc2({{"dow", {0, "0000000"}}});
+ BOOST_CHECK(dc2.match() == false);
+}
+
+BOOST_AUTO_TEST_CASE( testtimeCondition )
+{
+ // 1330895302 => So 4. Mär 22:08:23 CET 2012
+ {
+ // Equal
+ timeCondition tcEq1({{"operator", {0, "="}}, {"value", {0, "22:08"}}}, 1330895302);
+ BOOST_CHECK(tcEq1.match() == true);
+ timeCondition tcEq2({{"operator", {0, "="}}, {"value", {0, "22:09"}}}, 1330895302);
+ BOOST_CHECK(tcEq2.match() == false);
+ }
+
+ {
+ // Not Equal
+ timeCondition tcNEq1({{"operator", {0, "!="}}, {"value", {0, "22:08"}}}, 1330895302);
+ BOOST_CHECK(tcNEq1.match() == false);
+ timeCondition tcNEq2({{"operator", {0, "!="}}, {"value", {0, "22:09"}}}, 1330895302);
+ BOOST_CHECK(tcNEq2.match() == true);
+ }
+
+ {
+ // Greater
+ timeCondition tcGt1({{"operator", {0, ">"}}, {"value", {0, "20:00"}}}, 1330895302);
+ BOOST_CHECK(tcGt1.match() == true);
+ timeCondition tcGt2({{"operator", {0, ">"}}, {"value", {0, "23:00"}}}, 1330895302);
+ BOOST_CHECK(tcGt2.match() == false);
+ timeCondition tcGt3({{"operator", {0, ">"}}, {"value", {0, "22:08"}}}, 1330895302);
+ BOOST_CHECK(tcGt3.match() == false);
+ }
+
+ {
+ // Less
+ timeCondition tcLt1({{"operator", {0, "<"}}, {"value", {0, "20:00"}}}, 1330895302);
+ BOOST_CHECK(tcLt1.match() == false);
+ timeCondition tcLt2({{"operator", {0, "<"}}, {"value", {0, "23:00"}}}, 1330895302);
+ BOOST_CHECK(tcLt2.match() == true);
+ timeCondition tcLt3({{"operator", {0, "<"}}, {"value", {0, "22:08"}}}, 1330895302);
+ BOOST_CHECK(tcLt3.match() == false);
+ }
+
+ {
+ // Greater or Equal
+ timeCondition tcGoE1({{"operator", {0, ">="}}, {"value", {0, "20:00"}}}, 1330895302);
+ BOOST_CHECK(tcGoE1.match() == true);
+ timeCondition tcGoE2({{"operator", {0, ">="}}, {"value", {0, "23:00"}}}, 1330895302);
+ BOOST_CHECK(tcGoE2.match() == false);
+ timeCondition tcGoE3({{"operator", {0, ">="}}, {"value", {0, "22:08"}}}, 1330895302);
+ BOOST_CHECK(tcGoE3.match() == true);
+ }
+
+ {
+ // Less or Equal
+ timeCondition tcLoE1({{"operator", {0, "<="}}, {"value", {0, "20:00"}}}, 1330895302);
+ BOOST_CHECK(tcLoE1.match() == false);
+ timeCondition tcLoE2({{"operator", {0, "<="}}, {"value", {0, "23:00"}}}, 1330895302);
+ BOOST_CHECK(tcLoE2.match() == true);
+ timeCondition tcLoE3({{"operator", {0, "<="}}, {"value", {0, "22:08"}}}, 1330895302);
+ BOOST_CHECK(tcLoE3.match() == true);
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END();
Modified: xPLHAL/branches/thomas_s_dev/test/test_determinator_manager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/test_determinator_manager.cpp 2012-03-04 21:45:41 UTC (rev 721)
+++ xPLHAL/branches/thomas_s_dev/test/test_determinator_manager.cpp 2012-03-04 22:02:54 UTC (rev 722)
@@ -13,7 +13,6 @@
{
DeterminatorManager dm("determinators");
dm.loadDeterminators();
-
}
BOOST_AUTO_TEST_SUITE_END();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tho...@us...> - 2012-04-30 21:05:47
|
Revision: 775
http://openautomation.svn.sourceforge.net/openautomation/?rev=775&view=rev
Author: thomas_s
Date: 2012-04-30 21:05:40 +0000 (Mon, 30 Apr 2012)
Log Message:
-----------
- added some documentation
- reworked xplcache
- almost replaced boost::posix_time with chrono
WIP
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/determinator.cpp
xPLHAL/branches/thomas_s_dev/src/determinator.h
xPLHAL/branches/thomas_s_dev/src/determinator_manager.h
xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
xPLHAL/branches/thomas_s_dev/src/devicemanager.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/recurring_timer.h
xPLHAL/branches/thomas_s_dev/src/xhcp.cpp
xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp
xPLHAL/branches/thomas_s_dev/src/xplcache.cpp
xPLHAL/branches/thomas_s_dev/src/xplcache.h
xPLHAL/branches/thomas_s_dev/src/xpldevice.h
xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-04-30 21:05:40 UTC (rev 775)
@@ -21,7 +21,7 @@
file(GLOB_RECURSE Condition_sources ./conditions/*.cpp)
#set(CMAKE_CXX_FLAGS "-g -std=c++0x")
-set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp
xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp
xhcp.cpp xplmessage.cpp recurring_timer.cpp main.cpp pugixml.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -64,16 +64,28 @@
// cerr << "Load result: " << result.description() << "\n";
}
+/**
+ * \brief register handler for XML parser
+ * this allowes to extend the parser with more conditions
+ */
void DeterminatorXmlParser::registerCondition(BaseDeterminatorItemConstPtr condition)
{
m_conditionmap[condition->item_name] = condition;
}
+/**
+ * \brief register handler for XML parser
+ * this allowes to extend the parser with more actions
+ */
void DeterminatorXmlParser::registerAction(BaseDeterminatorItemConstPtr action)
{
m_actionmap[action->item_name] = action;
}
+/**
+ * \brief Parse the filen given in constructor
+ * \return Determinator object
+ */
Determinator DeterminatorXmlParser::parse()
{
try {
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -7,6 +7,13 @@
#include <thread>
#include <future>
+/**
+ * \brief Determinator implementation.
+ *
+ * A Determinator is configured with an XML-File.
+ * When all input conditions are met (true) the Determinator is executed:
+ * All output actions are executed in the 'executeOrder' order.
+ */
class Determinator
{
public:
@@ -15,8 +22,15 @@
enum class match_type { ALL, ANY };
+ /**
+ * \brief Print Determinator in human-readable form to console
+ */
void printDeterminator() const;
+ /**
+ * \brief Check if input conditions are met, then start a thread to execute actions
+ * The output-actions are executed in a seperate thread.
+ */
void execute();
std::string guid;
@@ -38,6 +52,9 @@
typedef std::shared_ptr<Determinator> DeterminatorPtr;
typedef std::shared_ptr<const Determinator> DeterminatorConstPtr;
+/**
+ * \brief Converts a Determinator from XML to internal Object format
+ */
class DeterminatorXmlParser
{
public:
Modified: xPLHAL/branches/thomas_s_dev/src/determinator_manager.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator_manager.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/determinator_manager.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -5,15 +5,23 @@
#include <boost/signals2/signal.hpp>
#include "xplhandler.h"
+/**
+ * \brief Manages Determinators in a filesystem directory
+ */
class DeterminatorManager
{
public:
DeterminatorManager(const std::string& determinatorDirectory);
+ /** \brief load Determinators from disk */
void loadDeterminators();
// DeterminatorConstPtr getDeterminator(const std::string& guid) const;
+
+ /** \brief get Determinator with GUID guid as std::string */
std::string getXmlDeterminator(const std::string& guid) const;
+
+ /** \brief store a XML-Formatted Determinator with guid on disk */
void storeXmlDeterminator(const std::string& guid, const std::string& xmlDeterminator);
public:
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -28,10 +28,6 @@
#include "devicemanager.h"
#include "i_xplcache.h"
-using boost::posix_time::ptime;
-using boost::posix_time::second_clock;
-using boost::posix_time::minutes;
-
using std::string;
using std::vector;
@@ -138,7 +134,7 @@
// A config list turned up that we haven't asked for...
// create a new device...
int interval = 5;
- ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
+ steady_time_point expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = false; // true = no config file, no response from device, false = have/waiting config
@@ -188,7 +184,7 @@
}
}
-ptime DeviceManager::calculateExpireTime(const string& string_interval, int *pInterval)
+steady_time_point DeviceManager::calculateExpireTime(const string& string_interval, int *pInterval)
{
int interval = string_interval.empty() ? atoi(string_interval.c_str()) : 5; // default to 5 minutes
if (pInterval) {
@@ -197,9 +193,9 @@
return calculateExpireTime(interval);
}
-ptime DeviceManager::calculateExpireTime(int interval)
+steady_time_point DeviceManager::calculateExpireTime(int interval)
{
- return second_clock::local_time() + minutes( 2* interval + 1 );
+ return std::chrono::steady_clock::now() + std::chrono::minutes( 2* interval + 1 );
}
void DeviceManager::processConfigHeartBeat( const xPLMessagePtr message )
@@ -212,7 +208,7 @@
// this handles a new application that identifies itself with a hbeat straight away.
// it must either be storing it's config locally, can't be configured, or is configured somewhere else.
int interval = 5;
- ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
+ steady_time_point expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = true; // true = no config file, no response from device, false = have/waiting config
@@ -254,7 +250,7 @@
// => just treat it like an heartbeat
return processConfigHeartBeat( message );
} else {
-// ptime expires = calculateExpireTime(device.Interval);
+// steady_time_point expires = calculateExpireTime(device.Interval);
// m_xPLCache->updateEntry( "config." + source + ".expires", timeConverter(calculateExpireTime(device.Interval), false ));
m_xPLCache->updateEntry( "config." + source + ".current", "true", false );
}
@@ -288,7 +284,7 @@
xPLDevice device = getDevice( source );
int interval = 5;
- ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
+ steady_time_point expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
writeLog( "DeviceManager::processHeartbeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -69,8 +69,8 @@
xPLHandler::signal_t m_sigSendXplMessage;
private:
- boost::posix_time::ptime calculateExpireTime(int interval);
- boost::posix_time::ptime calculateExpireTime(const std::string& string_interval, int *pInterval = 0);
+ steady_time_point calculateExpireTime(int interval);
+ steady_time_point calculateExpireTime(const std::string& string_interval, int *pInterval = 0);
IxPLCacheClass* m_xPLCache;
std::map<std::string, xPLDevice> mDeviceMap;
Modified: xPLHAL/branches/thomas_s_dev/src/main.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -48,6 +48,9 @@
static boost::asio::io_service* g_ioservice = nullptr;
+/**
+ * \brief Main application
+ */
class XplHalApplication
{
public:
@@ -86,6 +89,9 @@
writeLog( "main: xPL shutdown", logLevel::all );
}
+ /**
+ * \brief Installs timer while constructing
+ */
void installTimer()
{
mTimerListAllObjects.sigExpired.connect([](const boost::system::error_code& e) {
@@ -99,11 +105,18 @@
});
}
+ /**
+ * \brief quit application
+ */
static void stop()
{
m_ioservice.stop();
}
+
+ /**
+ * \brief runs the Application (called from main)
+ */
int exec()
{
// force everyone to send their configuration so that we start up to date...
Modified: xPLHAL/branches/thomas_s_dev/src/recurring_timer.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/recurring_timer.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/recurring_timer.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -20,6 +20,11 @@
#include <boost/asio.hpp>
#include <boost/signals2/signal.hpp>
+/**
+ * \brief Self-repeating timer
+ * Based on the ASIO deadline_timer which only expires once this class
+ * implements a recurring timer.
+ */
class RecurringTimer
{
public:
@@ -29,6 +34,11 @@
void start();
void stop();
+ /**
+ * \brief Expired signal to connect to
+ * This member is public to make it more easy to connect to signal.
+ * So only connect/disconnect to this signal is allowed!
+ */
boost::signals2::signal<void (const boost::system::error_code& e)> sigExpired;
private:
Modified: xPLHAL/branches/thomas_s_dev/src/xhcp.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xhcp.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xhcp.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -22,8 +22,9 @@
#include "xhcp.h"
using boost::asio::ip::tcp;
+namespace a = boost::asio;
-XHCPServer::XHCPServer(boost::asio::io_service& io, DeviceManager* dm)
+XHCPServer::XHCPServer(a::io_service& io, DeviceManager* dm)
:m_io(io)
,m_acceptor(io, tcp::endpoint(tcp::v4(), 3865))
,m_dm(dm)
Modified: xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -18,6 +18,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
+#include <ctime>
#include "globals.h"
#include "xplcache.h"
@@ -37,6 +38,8 @@
using std::string;
using std::vector;
+namespace ba = boost::asio;
+
XHCPThread::XHCPThread( socket_ptr socket, DeviceManager* dm )
: m_stoprequested(false)
, tab( "\t" )
@@ -120,11 +123,11 @@
// commands[ "SETSETTING" ] = &XHCPThread::;
commands[ "QUIT" ] = &XHCPThread::commandQuit;
- boost::asio::streambuf sb;
+ ba::streambuf sb;
boost::system::error_code error;
string greeting( "200 CHRISM-XPLHAL.SERVER1 Version 0.0 alpha XHCP 1.5 ready\r\n" );
- boost::asio::write(*sock, boost::asio::buffer(greeting));
+ ba::write(*sock, ba::buffer(greeting));
while (!quit) {
// const int TimeoutInCommand = 5 * 1000; // during transmission of an command
@@ -135,17 +138,17 @@
|| ( inMultilineRequest && endDifferent(data, "\r\n.\r\n") ) ) {
//int Timeout = (""==data) ? TimeoutExCommand : TimeoutInCommand;
- std::size_t n = boost::asio::read_until(*sock, sb, '\n');
- boost::asio::streambuf::const_buffers_type bufs = sb.data();
+ std::size_t n = ba::read_until(*sock, sb, '\n');
+ ba::streambuf::const_buffers_type bufs = sb.data();
string newData(
- boost::asio::buffers_begin(bufs),
- boost::asio::buffers_begin(bufs) + n);
+ ba::buffers_begin(bufs),
+ ba::buffers_begin(bufs) + n);
sb.consume(n);
/*
string newData;
- size_t length = sock->read_some(boost::asio::buffer(newData), error);
+ size_t length = sock->read_some(ba::buffer(newData), error);
- if (error == boost::asio::error::eof)
+ if (error == ba::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.*/
@@ -164,7 +167,7 @@
string result = (this->*multilineRequestHandler)( data );
writeLog( "Result:\n[\n" + result + "]", logLevel::debug );
//socket.write( result );
- boost::asio::write(*sock, boost::asio::buffer(result));
+ ba::write(*sock, ba::buffer(result));
}
else {
data.erase( data.size()-2 ); // chop
@@ -185,7 +188,7 @@
writeLog( "Request: [" + data + "]", logLevel::debug );
string result = (this->*command)( parameters );
writeLog( "Result:\n[\n" + result + "]", logLevel::debug );
- boost::asio::write(*sock, boost::asio::buffer(result));
+ ba::write(*sock, ba::buffer(result));
}
}
@@ -328,6 +331,16 @@
return result;
}
+template<typename D, typename F>
+std::string date2String(const D& date, const F& format)
+{
+ char tmp[50];
+ std::time_t time_ = D::clock::to_time_t(date);
+ int r = strftime(tmp, sizeof(tmp)-1, format, std::localtime(&time_));
+ tmp[r] = 0;
+ return tmp;
+}
+
string XHCPThread::commandListDevices( const string& parameter )
{
writeLog( "XHCPThread::commandListGlobals( " + parameter + " )", logLevel::debug );
@@ -345,7 +358,7 @@
if( showDevice && !device.Suspended )
{
result += device.VDI + tab;
- result += timeConverter( device.Expires ) + tab;
+ result += date2String(device.Expires, "%d.%m.%Y %H:%M:%S");
result += lexical_cast<string>( device.Interval ) + tab;
result += (device.ConfigType ? "Y" : "N") + tab;
result += (device.ConfigDone ? "Y" : "N") + tab;
Modified: xPLHAL/branches/thomas_s_dev/src/xplcache.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplcache.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xplcache.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -1,23 +1,23 @@
/*
- xPLHAL implementation in C++
- Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
+ xPLHAL implementation in C++
+ Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
- 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 3 of the License, or
- (at your option) any later version.
+ 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 3 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.
+ 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, see <http://www.gnu.org/licenses/>.
-*/
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include <boost/algorithm/string.hpp>
-#include <boost/thread/locks.hpp>
+#include <algorithm>
#include "globals.h"
#include "log.h"
@@ -28,140 +28,146 @@
using boost::algorithm::iequals;
using boost::algorithm::is_any_of;
using boost::algorithm::split;
-using boost::posix_time::minutes;
-using boost::posix_time::second_clock;
-using boost::filesystem::path;
+namespace BFS = boost::filesystem;
+
using std::string;
using std::vector;
+using std::mutex;
+using std::lock_guard;
-timeStreamHelper timeConverter;
+//timeStreamHelper timeConverter;
+
xPLCacheClass::CacheFilter::CacheFilter() :
- prefTag( "cache" ), mfType( "*" ), mfVendor( "*" ), mfDevice( "*" ),
- mfInstance( "*" ), mfSchemType( "*" ), mfSchemClass( "*" ), expiry( false )
+ prefTag( "cache" ), mfType( "*" ), mfVendor( "*" ), mfDevice( "*" ),
+ mfInstance( "*" ), mfSchemType( "*" ), mfSchemClass( "*" ), expiry( false )
{}
xPLCacheClass::CacheFilter::CacheFilter( const string& filter ) :
- prefTag( "cache" ), expiry( false )
+ prefTag( "cache" ), expiry( false )
{
- vector<string> list;
- split( list, filter, is_any_of(".") );
- mfType = list[0];
- mfVendor = list[1];
- mfDevice = list[2];
- mfInstance = list[3];
- mfSchemType = list[4];
- mfSchemClass = list[5];
+ vector<string> list;
+ split( list, filter, is_any_of(".") );
+ mfType = list[0];
+ mfVendor = list[1];
+ mfDevice = list[2];
+ mfInstance = list[3];
+ mfSchemType = list[4];
+ mfSchemClass = list[5];
}
xPLCacheClass::xPLCacheClass()
{
- loadCache();
+ loadCache();
}
string xPLCacheClass::listAllObjects( bool forceEverything ) const
{
- writeLog( "xPLCacheClass::ListAllObjects()", logLevel::debug );
+ writeLog( "xPLCacheClass::ListAllObjects()", logLevel::debug );
- string result;
- shared_lock locker(cacheLock);
+ string result;
+ lock_guard<mutex> locker(mCachelock);
- for( cacheMap::const_iterator it = cache.begin(); it != cache.end(); it++ )
- {
- string name = it->first;
- if( starts_with( name, "device." ) )
- {
- if( forceEverything || iequals( "true", cache.find("xplhal.showdevices")->second.value ) )
- result += name + "=" + it->second.value + "\r\n";
+ for( auto &it : mCache ) {
+ string name = it.first;
+ if( starts_with( name, "device." ) ) {
+ if( forceEverything || iequals( "true", mCache.find("xplhal.showdevices")->second.value ) )
+ result += name + "=" + it.second.value + "\r\n";
+ }
+ else if( starts_with( name, "config." ) ) {
+ if( forceEverything || iequals( "true", mCache.find("xplhal.showconfigs")->second.value ) )
+ result += name + "=" + it.second.value + "\r\n";
+ }
+ else {
+ result += name + "=" + it.second.value + "\r\n";
+ }
}
- else if( starts_with( name, "config." ) )
- {
- if( forceEverything || iequals( "true", cache.find("xplhal.showconfigs")->second.value ) )
- result += name + "=" + it->second.value + "\r\n";
- }
- else
- {
- result += name + "=" + it->second.value + "\r\n";
- }
- }
- writeLog( "shared_lock locker(cacheLock): about to be destructed", logLevel::debug );
- return result;
+ writeLog( "shared_lock locker(cacheLock): about to be destructed", logLevel::debug );
+ return result;
}
void xPLCacheClass::updateEntry( const string& name, const string& value, const bool expires )
{
- writeLog( "xPLCacheClass::updateEntry( \"" + name + "\", \"" + value + "\" )", logLevel::debug );
- unique_lock locker(cacheLock);
+ writeLog( "xPLCacheClass::updateEntry( \"" + name + "\", \"" + value + "\" )", logLevel::debug );
+ lock_guard<mutex> locker(mCachelock);
- cacheMap::iterator it = cache.find( name );
- if( cache.end() == it )
- cache.insert( std::pair<string,CacheEntry>( name, CacheEntry( value, expires ) ) );
- else
- it->second = CacheEntry( value, expires );
+ auto it = mCache.find( name );
+ if( mCache.end() == it ) {
+ mCache.insert({name, CacheEntry( value, expires )});
+ }
+ else {
+ it->second = CacheEntry( value, expires );
+ }
}
void xPLCacheClass::deleteEntry( const string& name )
{
- writeLog( "xPLCacheClass::deleteEntry( \"" + name + "\" )", logLevel::debug );
- unique_lock locker(cacheLock);
- cache.erase( name );
+ writeLog( "xPLCacheClass::deleteEntry( \"" + name + "\" )", logLevel::debug );
+ lock_guard<mutex> locker(mCachelock);
+ mCache.erase( name );
}
+template<typename Map, typename F>
+void map_erase_if(Map& m, F pred)
+{
+ for (typename Map::iterator i = m.begin();
+ (i = std::find_if(i, m.end(), pred)) != m.end();
+ m.erase(i++));
+}
+
void xPLCacheClass::flushExpiredEntries( void )
{
- writeLog( "xPLCacheClass::flushExpiredEntries()", logLevel::debug );
- unique_lock locker(cacheLock);
- for( cacheMap::iterator it = cache.begin(); it != cache.end(); )
- {
- // delete if entry is older than 15 minutes
- if( it->second.expiry && (it->second.date < second_clock::local_time() - minutes( 15 )) )
- cache.erase( it++ );
- else
- ++it;
- }
+ writeLog( "xPLCacheClass::flushExpiredEntries()", logLevel::debug );
+ lock_guard<mutex> locker(mCachelock);
+
+ map_erase_if(mCache, [](cachemap_t::value_type &cache) {
+ return cache.second.isExpired();
+ });
}
vector<string> xPLCacheClass::childNodes( const string& filter ) const
{
- vector<string> retval;
+ vector<string> retval;
- for( cacheMap::const_iterator it = cache.begin(); it != cache.end(); ++it )
- if( starts_with( it->first, filter ) )
- retval.push_back( it->first );
+ for(auto &it : mCache) {
+ if( starts_with( it.first, filter ) ) {
+ retval.push_back( it.first );
+ }
+ }
- return retval;
+ return retval;
}
vector<string> xPLCacheClass::filterByRegEx( const boost::regex& regex ) const
{
- vector<string> retval;
+ vector<string> retval;
- for( cacheMap::const_iterator it = cache.begin(); it != cache.end(); ++it )
- {
- if( boost::regex_match( it->first, regex ) )
- retval.push_back( it->first );
- }
+ for(auto &it : mCache) {
+ if( boost::regex_match( it.first, regex ) ) {
+ retval.push_back( it.first );
+ }
+ }
- return retval;
+ return retval;
}
void xPLCacheClass::loadCache( void )
{
- cache.clear(); // erase all entries
+ mCache.clear(); // erase all entries
- path objectCacheFile( DataFileFolder / "object_cache.xml" );
- writeLog( "loadCache: ["+objectCacheFile.string()+"]", logLevel::debug );
- if( boost::filesystem::exists( objectCacheFile ) )
- {
- writeLog( "Loading cached xPL object from file: "+objectCacheFile.string(), logLevel::debug );
- } else {
- writeLog( "No xPL object cache file found at: "+objectCacheFile.string()+" - creating a new one...", logLevel::debug );
- updateEntry( "xplhal.period" , "0" , false );
- updateEntry( "xplhal.mode" , "0" , false );
- updateEntry( "xplhal.showdevices", "true", false );
- updateEntry( "xplhal.showconfigs", "true", false );
- }
+ BFS::path objectCacheFile( DataFileFolder / "object_mCache.xml" );
+ writeLog( "loadCache: ["+objectCacheFile.string()+"]", logLevel::debug );
+ if( BFS::exists( objectCacheFile ) ) {
+ writeLog( "Loading cached xPL object from file: "+objectCacheFile.string(), logLevel::debug );
+ }
+ else {
+ writeLog( "No xPL object cache file found at: "+objectCacheFile.string()+" - creating a new one...", logLevel::debug );
+ updateEntry( "xplhal.period" , "0" , false );
+ updateEntry( "xplhal.mode" , "0" , false );
+ updateEntry( "xplhal.showdevices", "true", false );
+ updateEntry( "xplhal.showconfigs", "true", false );
+ }
}
void xPLCacheClass::saveCache( void ) const
Modified: xPLHAL/branches/thomas_s_dev/src/xplcache.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplcache.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xplcache.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -1,61 +1,35 @@
#pragma once
/*
- xPLHAL implementation in C++
- Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
+ xPLHAL implementation in C++
+ Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
- 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 3 of the License, or
- (at your option) any later version.
+ 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 3 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.
+ 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, see <http://www.gnu.org/licenses/>.
-*/
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include <string>
#include <vector>
#include <map>
+#include <chrono>
+#include <thread>
-#include <boost/thread/shared_mutex.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
#include "i_xplcache.h"
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define steady_clock monotonic_clock
+#endif
-/** Helper function */
-class timeStreamHelper
-{
- std::stringstream timeStream;
- public:
- timeStreamHelper()
- {
- boost::posix_time::time_facet* output_facet = new boost::posix_time::time_facet( "%d.%m.%Y %H:%M:%S" );
- timeStream.imbue(std::locale(timeStream.getloc(), output_facet));
- boost::posix_time::time_input_facet* input_facet = new boost::posix_time::time_input_facet( "%d.%m.%Y %H:%M:%S" );
- timeStream.imbue(std::locale(timeStream.getloc(), input_facet));
- }
- std::string operator()( const boost::posix_time::ptime& time )
- {
- timeStream.str("");
- timeStream << time;
- return timeStream.str();
- }
- boost::posix_time::ptime operator()( const std::string& time )
- {
- boost::posix_time::ptime retval;
- timeStream.str("");
- timeStream << time;
- timeStream >> retval;
- return retval;
- }
-};
-extern timeStreamHelper timeConverter;
-
/**
* \class xPLCacheClass
*
@@ -65,91 +39,106 @@
*/
class xPLCacheClass: public IxPLCacheClass
{
- protected:
- /**
- * \brief Representation of a xPL value in the cache.
- */
- struct CacheEntry
- {
- std::string value; /**< \brief Value of the xPL message. */
- boost::posix_time::ptime date; /**< \brief Timestamp of time of entry. */
- bool expiry; /**< \brief Flag if this entry should expire. */
+ protected:
+ /**
+ * \brief Representation of a xPL value in the cache.
+ */
+ struct CacheEntry
+ {
+ //! \brief Value of the xPL message.
+ std::string value;
+
+ //! \brief Timestamp of time of...
[truncated message content] |
|
From: <tho...@us...> - 2012-07-02 20:41:26
|
Revision: 901
http://openautomation.svn.sourceforge.net/openautomation/?rev=901&view=rev
Author: thomas_s
Date: 2012-07-02 20:41:20 +0000 (Mon, 02 Jul 2012)
Log Message:
-----------
make it compile with g++-4.7
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/determinator.cpp
xPLHAL/branches/thomas_s_dev/src/determinator.h
xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/recurring_timer.cpp
xPLHAL/branches/thomas_s_dev/src/recurring_timer.h
xPLHAL/branches/thomas_s_dev/src/xplcache.h
xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-07-02 20:41:20 UTC (rev 901)
@@ -21,7 +21,7 @@
file(GLOB_RECURSE Condition_sources ./conditions/*.cpp)
#set(CMAKE_CXX_FLAGS "-g -std=c++0x")
-set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -Os -std=c++11 -ffunction-sections -fdata-sections")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp
xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp
xhcp.cpp xplmessage.cpp recurring_timer.cpp main.cpp pugixml.cpp
@@ -34,5 +34,5 @@
#message(STATUS "Boost_LIBRARIES=${Boost_LIBRARIES}")
#message(STATUS "LIBRARIES=${LIBS}")
#target_link_libraries(xPLHAL ${Boost_LIBRARIES} -dynamic xPL pthread -static)
-target_link_libraries(xPLHAL ${LIBS})
+target_link_libraries(xPLHAL ${LIBS} -ffunction-sections -fdata-sections)
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-07-02 20:41:20 UTC (rev 901)
@@ -201,9 +201,10 @@
{
if (checkInputs()) {
if (mExecFutures.empty() || mExecFutures[0].valid()) {
- mExecFutures.erase(mExecFutures.begin(), mExecFutures.end());
+ mExecFutures.clear();
+// mExecFutures.erase(mExecFutures.begin(), mExecFutures.end());
cerr << "determinator start thread" << endl;
- mExecFutures.push_back(std::async(std::launch::async, std::bind(&Determinator::executeOutputs, this)));
+ mExecFutures.emplace_back(std::async(std::launch::async, std::bind(&Determinator::executeOutputs, this)));
cerr << "determinator start thread" << endl;
}
}
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-07-02 20:41:20 UTC (rev 901)
@@ -46,7 +46,7 @@
bool checkInputs() const;
bool executeOutputs() const;
- std::vector<std::future<bool>> mExecFutures;
+ std::vector<std::shared_future<bool>> mExecFutures;
};
typedef std::shared_ptr<Determinator> DeterminatorPtr;
Modified: xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/determinator_manager.cpp 2012-07-02 20:41:20 UTC (rev 901)
@@ -31,7 +31,7 @@
for (auto item = directory_iterator(p); item != directory_iterator(); ++item) {
ifstream determinatorFile(*item);
- std::string filename = item->string();
+ std::string filename = item->path().string();
//storeXmlDeterminator("guid", determinatorFile.read());
cout << "diritem: " << *item << "\n";
DeterminatorXmlParser parser(filename);
Modified: xPLHAL/branches/thomas_s_dev/src/main.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-07-02 20:41:20 UTC (rev 901)
@@ -29,7 +29,7 @@
#include "globals.h"
using boost::filesystem::path;
-using boost::filesystem::initial_path;
+using boost::filesystem::current_path;
using boost::program_options::options_description;
using boost::program_options::variables_map;
using boost::program_options::store;
Modified: xPLHAL/branches/thomas_s_dev/src/recurring_timer.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/recurring_timer.cpp 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/recurring_timer.cpp 2012-07-02 20:41:20 UTC (rev 901)
@@ -16,10 +16,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "recurring_timer.h"
-#include <boost/bind.hpp>
+using namespace std::placeholders;
+
RecurringTimer::RecurringTimer(boost::asio::io_service& io_service,
- const boost::asio::deadline_timer::duration_type& expiry_time,
+ const boost::asio::steady_timer::duration& expiry_time,
bool startTimer)
:m_timer(io_service, expiry_time)
,m_delay(expiry_time)
@@ -38,7 +39,7 @@
void RecurringTimer::start()
{
m_running = true;
- m_timer.async_wait(boost::bind(&RecurringTimer::onExpire, this, _1));
+ m_timer.async_wait(std::bind(&RecurringTimer::onExpire, this, _1));
}
void RecurringTimer::stop()
@@ -51,7 +52,7 @@
{
if (m_running) {
m_timer.expires_at(m_timer.expires_at() + m_delay);
- m_timer.async_wait(boost::bind(&RecurringTimer::onExpire, this, _1));
+ m_timer.async_wait(std::bind(&RecurringTimer::onExpire, this, _1));
}
sigExpired(e);
}
Modified: xPLHAL/branches/thomas_s_dev/src/recurring_timer.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/recurring_timer.h 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/recurring_timer.h 2012-07-02 20:41:20 UTC (rev 901)
@@ -17,7 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define BOOST_BIND_NO_PLACEHOLDERS
#include <boost/asio.hpp>
+#include <boost/asio/steady_timer.hpp>
#include <boost/signals2/signal.hpp>
/**
@@ -28,7 +30,7 @@
class RecurringTimer
{
public:
- RecurringTimer(boost::asio::io_service& io_service, const boost::asio::deadline_timer::duration_type& expiry_time, bool startTimer = false);
+ RecurringTimer(boost::asio::io_service& io_service, const boost::asio::steady_timer::duration& expiry_time, bool startTimer = false);
~RecurringTimer();
void start();
@@ -44,8 +46,8 @@
private:
void onExpire(const boost::system::error_code& e);
- const boost::asio::deadline_timer::duration_type m_delay;
+ const boost::asio::steady_timer::duration m_delay;
bool m_running;
- boost::asio::deadline_timer m_timer;
+ boost::asio::steady_timer m_timer;
};
Modified: xPLHAL/branches/thomas_s_dev/src/xplcache.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplcache.h 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/src/xplcache.h 2012-07-02 20:41:20 UTC (rev 901)
@@ -21,14 +21,17 @@
#include <vector>
#include <map>
#include <chrono>
-#include <thread>
+#include <mutex>
#include <boost/regex.hpp>
#include "i_xplcache.h"
+
+#if !((__GNUG__ >= 4) && (__GNUC_MINOR__ >= 7))
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#define steady_clock monotonic_clock
#endif
+#endif
/**
* \class xPLCacheClass
Modified: xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt 2012-07-02 20:40:52 UTC (rev 900)
+++ xPLHAL/branches/thomas_s_dev/test/CMakeLists.txt 2012-07-02 20:41:20 UTC (rev 901)
@@ -35,7 +35,7 @@
enable_testing()
-set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x -fprofile-arcs -ftest-coverage")
+set(CMAKE_CXX_FLAGS "-g -Os -std=c++11 -fprofile-arcs -ftest-coverage")
#set(xPLHALTest_SRCS test_test.cpp test_xplcache.cpp)
#add_executable(test_runner ${xPLHALTest_SRCS})
#message(STATUS "Boost_LIBRARIES=${Boost_LIBRARIES}")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|