From bffb76e72ca7430bdf719a8a7104a7859fab9d9c Mon Sep 17 00:00:00 2001 From: blaakmeer <sdos@astron.nl> Date: Thu, 14 Sep 2006 21:05:55 +0000 Subject: [PATCH] BugID: 803 First version of OfflineControl --- .../OfflineControl/CEPApplicationManager.cc | 129 +++ .../OfflineControl/CEPApplicationManager.h | 230 +++++ MAC/APL/CEPCU/src/OfflineControl/Makefile.am | 38 + .../src/OfflineControl/OfflineControl.cc | 853 ++++++++++++++++++ .../CEPCU/src/OfflineControl/OfflineControl.h | 154 ++++ .../OfflineControl/OfflineControl.log_prop.in | 20 + .../OfflineControl/OfflineControlDefines.h | 43 + .../src/OfflineControl/OfflineControlMain.cc | 52 ++ 8 files changed, 1519 insertions(+) create mode 100644 MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.cc create mode 100644 MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.h create mode 100644 MAC/APL/CEPCU/src/OfflineControl/Makefile.am create mode 100644 MAC/APL/CEPCU/src/OfflineControl/OfflineControl.cc create mode 100644 MAC/APL/CEPCU/src/OfflineControl/OfflineControl.h create mode 100644 MAC/APL/CEPCU/src/OfflineControl/OfflineControl.log_prop.in create mode 100644 MAC/APL/CEPCU/src/OfflineControl/OfflineControlDefines.h create mode 100644 MAC/APL/CEPCU/src/OfflineControl/OfflineControlMain.cc diff --git a/MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.cc b/MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.cc new file mode 100644 index 00000000000..89ce40b8011 --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.cc @@ -0,0 +1,129 @@ +//# CEPApplicationManager.cc: Implementation of the Virtual CEPApplicationManager task +//# +//# Copyright (C) 2002-2004 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include <lofar_config.h> +#include "CEPApplicationManager.h" + +namespace LOFAR +{ + +using namespace ACC::ALC; + + namespace CEPCU + { +INIT_TRACER_CONTEXT(CEPApplicationManager, LOFARLOGGER_PACKAGE); + + +void CEPApplicationManager::workProc() +{ + if (_continuePoll) + { + _acClient.processACmsgFromServer(); + } +} + +void CEPApplicationManager::handleAckMsg(ACCmd cmd, + uint16 result, + const string& info) +{ + LOG_INFO(formatString("command: %d, result: %d, info: %s", cmd, result, info.c_str())); + switch (cmd) + { + case ACCmdBoot: + if (result == AcCmdMaskOk) + { + _lastOkCmd = cmd; + } + _interface.appBooted(_procName, result); + break; + + case ACCmdQuit: + if (result == AcCmdMaskOk && result == 0) + { + _continuePoll = false; + } + _interface.appQuitDone(_procName, result); + break; + + case ACCmdDefine: + if (result == AcCmdMaskOk) + { + _lastOkCmd = cmd; + } + _interface.appDefined(_procName, result); + break; + + case ACCmdInit: + if (result == AcCmdMaskOk) + { + _lastOkCmd = cmd; + } + _interface.appInitialized(_procName, result); + break; + + case ACCmdPause: + _interface.appPaused(_procName, result); + break; + + case ACCmdRun: + if (result == AcCmdMaskOk) + { + _lastOkCmd = cmd; + } + _interface.appRunDone(_procName, result); + break; + + case ACCmdSnapshot: + _interface.appSnapshotDone(_procName, result); + break; + + case ACCmdRecover: + _interface.appRecovered(_procName, result); + break; + + case ACCmdReinit: + _interface.appReinitialized(_procName, result); + break; + + case ACCmdReplace: + _interface.appReplaced(_procName, result); + break; + + default: + LOG_WARN_STR("Received command = " << cmd << ", result = " << result + << ", info = " << info << " not handled!"); + break; + } +} + +void CEPApplicationManager::handleAnswerMsg (const string& answer) +{ + _interface.appSupplyInfoAnswer(_procName, answer); +} + +string CEPApplicationManager::supplyInfoFunc (const string& keyList) +{ + return _interface.appSupplyInfo(_procName, keyList); +} + + } // namespace CEPCU +} // namespace LOFAR diff --git a/MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.h b/MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.h new file mode 100644 index 00000000000..0a0c45ab36e --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/CEPApplicationManager.h @@ -0,0 +1,230 @@ +//# CEPApplicationManager.h: factory class for Virtual Backends. +//# +//# Copyright (C) 2002-2005 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef CEPAPPLICATIONMANAGER_H +#define CEPAPPLICATIONMANAGER_H + +//# Includes +#include <ALC/ACAsyncClient.h> +#include <GCF/TM/GCF_Handler.h> + +//# local includes +//# Common Includes + +// forward declaration + +namespace LOFAR +{ + namespace CEPCU + { + +class CEPApplicationManagerInterface +{ + protected: + CEPApplicationManagerInterface() {} + + public: + virtual ~CEPApplicationManagerInterface() {} + + public: + virtual void appBooted(const string& procName, uint16 result) = 0; + virtual void appDefined(const string& procName, uint16 result) = 0; + virtual void appInitialized(const string& procName, uint16 result) = 0; + virtual void appRunDone(const string& procName, uint16 result) = 0; + virtual void appPaused(const string& procName, uint16 result) = 0; + virtual void appQuitDone(const string& procName, uint16 result) = 0; + virtual void appSnapshotDone(const string& procName, uint16 result) = 0; + virtual void appRecovered(const string& procName, uint16 result) = 0; + virtual void appReinitialized(const string& procName, uint16 result) = 0; + virtual void appReplaced(const string& procName, uint16 result) = 0; + virtual string appSupplyInfo(const string& procName, const string& keyList) = 0; + virtual void appSupplyInfoAnswer(const string& procName, const string& answer) = 0; + + private: + // protected copy constructor + CEPApplicationManagerInterface(const CEPApplicationManagerInterface&); + // protected assignment operator + CEPApplicationManagerInterface& operator=(const CEPApplicationManagerInterface&); +}; + +class CEPApplicationManager : public ACC::ALC::ACClientFunctions, + GCF::TM::GCFHandler +{ + public: + CEPApplicationManager(CEPApplicationManagerInterface& interface, const string& appName); + virtual ~CEPApplicationManager(); + + public: // methods may be called from specialized CEPApplicationManagerInterface + bool boot (const time_t scheduleTime, + const string& configID); + bool define (const time_t scheduleTime) const; + bool init (const time_t scheduleTime) const; + bool run (const time_t scheduleTime) const; + bool pause (const time_t scheduleTime, + const time_t maxWaitTime, + const string& condition) const; + bool quit (const time_t scheduleTime) const; + bool shutdown (const time_t scheduleTime) const; + bool snapshot (const time_t scheduleTime, + const string& destination) const; + bool recover (const time_t scheduleTime, + const string& source) const; + bool reinit (const time_t scheduleTime, + const string& configID) const; + bool replace (const time_t scheduleTime, + const string& processList, + const string& nodeList, + const string& configID) const; + string askInfo (const string& keylist) const; + bool cancelCmdQueue () const; + ACC::ALC::ACCmd getLastOkCmd() const; + + private: // implemenation of abstract GCFHandler methods + friend class GCF::TM::GCFHandler; + void workProc(); + void stop(); + + private: // implemenation of abstract ACClientFunctions methods + friend class ACC::ALC::ACClientFunctions; + void handleAckMsg (ACC::ALC::ACCmd cmd, + uint16 result, + const string& info); + + void handleAnswerMsg (const string& answer); + + string supplyInfoFunc (const string& keyList); + + protected: + // protected copy constructor + CEPApplicationManager(const CEPApplicationManager&); + // protected assignment operator + CEPApplicationManager& operator=(const CEPApplicationManager&); + + private: + CEPApplicationManagerInterface& _interface; + ACC::ALC::ACAsyncClient _acClient; + bool _continuePoll; + ACC::ALC::ACCmd _lastOkCmd; + string _procName; + + ALLOC_TRACER_CONTEXT +}; + +inline CEPApplicationManager::CEPApplicationManager( + CEPApplicationManagerInterface& interface, + const string& appName) : + _interface(interface), + _acClient(this, appName, 10, 100, 1, 0), + _continuePoll(false), + _lastOkCmd(ACC::ALC::ACCmdNone), + _procName(appName) +{ + use(); // to avoid that this object will be deleted in GCFTask::stop; +} + +inline CEPApplicationManager::~CEPApplicationManager() +{ + GCFTask::deregisterHandler(*this); +} + +inline bool CEPApplicationManager::boot (const time_t scheduleTime, + const string& configID) +{ + _continuePoll = true; + return _acClient.boot(scheduleTime, configID); +} + +inline bool CEPApplicationManager::define (const time_t scheduleTime) const +{ + return _acClient.define(scheduleTime); +} + +inline bool CEPApplicationManager::init (const time_t scheduleTime) const +{ + return _acClient.init(scheduleTime); +} + +inline bool CEPApplicationManager::run (const time_t scheduleTime) const +{ + return _acClient.run(scheduleTime); +} + +inline bool CEPApplicationManager::pause (const time_t scheduleTime, + const time_t maxWaitTime, + const string& condition) const +{ + return _acClient.pause(scheduleTime, maxWaitTime, condition); +} + +inline bool CEPApplicationManager::quit (const time_t scheduleTime) const +{ + return _acClient.quit(scheduleTime); +} + +inline bool CEPApplicationManager::shutdown (const time_t scheduleTime) const +{ + return _acClient.shutdown(scheduleTime); +} + +inline bool CEPApplicationManager::snapshot (const time_t scheduleTime, + const string& destination) const +{ + return _acClient.snapshot(scheduleTime, destination); +} + +inline bool CEPApplicationManager::recover (const time_t scheduleTime, + const string& source) const +{ + return _acClient.recover(scheduleTime, source); +} + +inline bool CEPApplicationManager::reinit (const time_t scheduleTime, + const string& configID) const +{ + return _acClient.reinit(scheduleTime, configID); +} + +inline bool CEPApplicationManager::replace (const time_t scheduleTime, + const string& processList, + const string& nodeList, + const string& configID) const +{ + return _acClient.replace(scheduleTime, processList, nodeList, configID); +} + +inline bool CEPApplicationManager::cancelCmdQueue () const +{ + return _acClient.cancelCmdQueue(); +} + +inline ACC::ALC::ACCmd CEPApplicationManager::getLastOkCmd() const +{ + return _lastOkCmd; +} + +inline void CEPApplicationManager::stop() +{ +} + + } // namespace CEPCU +} // namespace LOFAR +#endif diff --git a/MAC/APL/CEPCU/src/OfflineControl/Makefile.am b/MAC/APL/CEPCU/src/OfflineControl/Makefile.am new file mode 100644 index 00000000000..106bb28c82f --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/Makefile.am @@ -0,0 +1,38 @@ +bin_PROGRAMS = OfflineControl + +OfflineControl_CPPFLAGS = -Wno-deprecated \ + -fmessage-length=0 \ + -fdiagnostics-show-location=once + +OfflineControl_SOURCES = CEPApplicationManager.cc \ + OfflineControl.cc \ + OfflineControlMain.cc + +OfflineControl_LDADD = $(LOFAR_DEPEND) +OfflineControl_DEPENDENCIES = $(LOFAR_DEPEND) + +NOINSTHDRS = CEPApplicationManager.h \ + OfflineControl.h \ + OfflineControlDefines.h + +INSTHDRS = + +pkginclude_HEADERS = $(NOINSTHDRS) $(INSTHDRS) + +DOCHDRS = $(pkginclude_HEADERS) $(BUILT_SOURCES) + +EXTRA_DIST = $(configfiles_DATA) $(sysconf_DATA) + +#in case of make install these files will be copied to the bindir beside the test apps +configfilesdir=$(bindir) +configfiles_DATA = + +sysconf_DATA = OfflineControl.log_prop + +%.log_prop: %.log_prop.in + cp $< $@ + +clean-local: + rm -f *.ph + +include $(top_srcdir)/Makefile.common diff --git a/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.cc b/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.cc new file mode 100644 index 00000000000..1b02f12aaf2 --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.cc @@ -0,0 +1,853 @@ +//# OfflineControl.cc: Implementation of the MAC Scheduler task +//# +//# Copyright (C) 2006 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ +#include <lofar_config.h> +#include <Common/LofarLogger.h> + +#include <boost/shared_array.hpp> +#include <APS/ParameterSet.h> +#include <APS/Exceptions.h> +#include <GCF/GCF_PVTypes.h> +#include <GCF/PAL/GCF_PVSSInfo.h> +#include <GCF/Utils.h> +#include <GCF/GCF_ServiceInfo.h> +#include <GCF/Protocols/PA_Protocol.ph> +#include <APL/APLCommon/APL_Defines.h> +#include <APL/APLCommon/APLUtilities.h> +#include <APL/APLCommon/APLCommonExceptions.h> +#include <APL/APLCommon/Controller_Protocol.ph> +#include <APL/APLCommon/StationInfo.h> +#include <APL/APLCommon/APLUtilities.h> + +#include "OfflineControl.h" +#include "OfflineControlDefines.h" + +using namespace LOFAR::GCF::Common; +using namespace LOFAR::GCF::TM; +using namespace LOFAR::GCF::PAL; +using namespace std; + +namespace LOFAR { + using namespace APLCommon; + using namespace ACC::APS; + using namespace ACC::ALC; + namespace CEPCU { + +// +// OfflineControl() +// +OfflineControl::OfflineControl(const string& cntlrName) : + GCFTask ((State)&OfflineControl::initial_state,cntlrName), + PropertySetAnswerHandlerInterface(), + itsPropertySetAnswer(*this), + itsPropertySet (), + itsPropertySetInitialized (false), + itsParentControl (0), + itsParentPort (0), + itsTimerPort (0), + itsCepApplications (), + itsCepAppParams (), + itsResultParams (), + itsProcessDependencies(), + itsState (CTState::NOSTATE), + itsTreePrefix (""), + itsInstanceNr (0), + itsStartTime (), + itsStopTime (), + itsClaimPeriod (), + itsPreparePeriod (), + itsCntlrName (cntlrName) +{ + LOG_TRACE_OBJ_STR (cntlrName << " construction"); + + // First readin our observation related config file. + LOG_DEBUG_STR("Reading parset file:" << LOFAR_SHARE_LOCATION << "/" << cntlrName); + globalParameterSet()->adoptFile(string(LOFAR_SHARE_LOCATION)+"/"+cntlrName); + + + // Readin some parameters from the ParameterSet. + itsTreePrefix = globalParameterSet()->getString("prefix"); + itsInstanceNr = globalParameterSet()->getUint32("_instanceNr"); + + // get Observation based information + itsStartTime = time_from_string(globalParameterSet()-> + getString("Observation.startTime")); + itsStopTime = time_from_string(globalParameterSet()-> + getString("Observation.stopTime")); + itsClaimPeriod = globalParameterSet()->getTime ("Observation.claimPeriod"); + itsPreparePeriod = globalParameterSet()->getTime ("Observation.preparePeriod"); + + // attach to parent control task + itsParentControl = ParentControl::instance(); + itsParentPort = new GCFITCPort (*this, *itsParentControl, "ParentITCport", + GCFPortInterface::SAP, CONTROLLER_PROTOCOL); + ASSERTSTR(itsParentPort, "Cannot allocate ITCport for Parentcontrol"); + itsParentPort->open(); // will result in F_CONNECTED + + // need port for timers. + itsTimerPort = new GCFTimerPort(*this, "TimerPort"); + + // for debugging purposes + registerProtocol (CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_signalnames); + registerProtocol (PA_PROTOCOL, PA_PROTOCOL_signalnames); + + setState(CTState::CREATED); +} + + +// +// ~OfflineControl() +// +OfflineControl::~OfflineControl() +{ + LOG_TRACE_OBJ_STR (getName() << " destruction"); + + if (itsPropertySet) { + itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("down")); + itsPropertySet->disable(); + } + + // ... +} + +// +// setState(CTstateNr) +// +void OfflineControl::setState(CTState::CTstateNr newState) +{ + itsState = newState; + + if (itsPropertySet) { + CTState cts; + itsPropertySet->setValue(string(PVSSNAME_FSM_STATE), + GCFPVString(cts.name(newState))); + } +} + + +// +// handlePropertySetAnswer(answer) +// +void OfflineControl::handlePropertySetAnswer(GCFEvent& answer) +{ + LOG_DEBUG_STR ("handlePropertySetAnswer:" << evtstr(answer)); + + switch(answer.signal) { + case F_MYPS_ENABLED: { + GCFPropSetAnswerEvent* pPropAnswer=static_cast<GCFPropSetAnswerEvent*>(&answer); + if(pPropAnswer->result != GCF_NO_ERROR) { + LOG_ERROR(formatString("%s : PropertySet %s NOT ENABLED", + getName().c_str(), pPropAnswer->pScope)); + } + // always let timer expire so main task will continue. + itsTimerPort->setTimer(1.0); + break; + } + + case F_PS_CONFIGURED: { + GCFConfAnswerEvent* pConfAnswer=static_cast<GCFConfAnswerEvent*>(&answer); + if(pConfAnswer->result == GCF_NO_ERROR) { + LOG_DEBUG(formatString("%s : apc %s Loaded", + getName().c_str(), pConfAnswer->pApcName)); + //apcLoaded(); + } + else { + LOG_ERROR(formatString("%s : apc %s NOT LOADED", + getName().c_str(), pConfAnswer->pApcName)); + } + break; + } + + case F_VGETRESP: + case F_VCHANGEMSG: { + // check which property changed + // GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer); + + // TODO: implement something usefull. + break; + } + +// case F_SUBSCRIBED: +// case F_UNSUBSCRIBED: +// case F_PS_CONFIGURED: +// case F_EXTPS_LOADED: +// case F_EXTPS_UNLOADED: +// case F_MYPS_ENABLED: +// case F_MYPS_DISABLED: +// case F_VGETRESP: +// case F_VCHANGEMSG: +// case F_SERVER_GONE: + + default: + break; + } +} + + +// +// initial_state(event, port) +// +// Setup all connections. +// +GCFEvent::TResult OfflineControl::initial_state(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("initial:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: + break; + + case F_INIT: { + // Get access to my own propertyset. + LOG_DEBUG ("Activating PropertySet"); + string propSetName = formatString(ONC_PROPSET_NAME, itsInstanceNr); + itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(), + ONC_PROPSET_TYPE, + PS_CAT_TEMPORARY, + &itsPropertySetAnswer)); + itsPropertySet->enable(); + // Wait for timer that is set in PropertySetAnswer on ENABLED event + } + break; + + case F_TIMER: + if (!itsPropertySetInitialized) { + itsPropertySetInitialized = true; + + // update PVSS. + LOG_TRACE_FLOW ("Updateing state to PVSS"); + itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("initial")); + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + + // Start ParentControl task + LOG_DEBUG ("Enabling ParentControl task"); + itsParentPort = itsParentControl->registerTask(this); + + LOG_DEBUG ("Going to operational state"); + TRAN(OfflineControl::active_state); // go to next state. + } + break; + + case F_CONNECTED: + ASSERTSTR (&port == itsParentPort, + "F_CONNECTED event from port " << port.getName()); + break; + + case F_DISCONNECTED: + break; + + default: + LOG_DEBUG_STR ("initial, default"); + status = GCFEvent::NOT_HANDLED; + break; + } + return (status); +} + + +// +// active_state(event, port) +// +// Normal operation state. +// +GCFEvent::TResult OfflineControl::active_state(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("active:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: { + // update PVSS + itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active")); + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + break; + } + + case F_INIT: + break; + + case F_ACCEPT_REQ: + break; + + case F_CONNECTED: { + ASSERTSTR (&port == itsParentPort, "F_CONNECTED event from port " << port.getName()); + break; + } + + case F_DISCONNECTED: { + port.close(); + break; + } + + case F_TIMER: +// GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); + break; + + // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- + case CONTROL_CONNECT: { + CONTROLConnectEvent msg(event); + LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")"); + setState(CTState::CONNECTED); + CONTROLConnectedEvent answer; + answer.cntlrName = msg.cntlrName; + port.send(answer); + break; + } + + case CONTROL_SCHEDULED: { + CONTROLScheduledEvent msg(event); + LOG_DEBUG_STR("Received SCHEDULED(" << msg.cntlrName << ")"); + // TODO: do something usefull with this information! + break; + } + + case CONTROL_CLAIM: { + CONTROLClaimEvent msg(event); + LOG_DEBUG_STR("Received CLAIM(" << msg.cntlrName << ")"); + setState(CTState::CLAIM); + setState(CTState::CLAIMED); + CONTROLClaimedEvent answer; + answer.cntlrName = getName(); + answer.result = doClaim(msg.cntlrName); + if(answer.result == CT_RESULT_NO_ERROR) + { + setState(CTState::CLAIMED); + } + port.send(answer); + + break; + } + + case CONTROL_PREPARE: { + CONTROLPrepareEvent msg(event); + LOG_DEBUG_STR("Received PREPARE(" << msg.cntlrName << ")"); + setState(CTState::PREPARE); + CONTROLPreparedEvent answer; + answer.cntlrName = getName(); + answer.result = doPrepare(msg.cntlrName); + if(answer.result == CT_RESULT_NO_ERROR) + { + setState(CTState::PREPARED); + } + port.send(answer); + break; + } + + case CONTROL_RESUME: { + CONTROLResumeEvent msg(event); + LOG_DEBUG_STR("Received RESUME(" << msg.cntlrName << ")"); + setState(CTState::ACTIVE); + // TODO: implement something useful + CONTROLResumedEvent answer; + answer.cntlrName = msg.cntlrName; + port.send(answer); + break; + } + + case CONTROL_SUSPEND: { + CONTROLSuspendEvent msg(event); + LOG_DEBUG_STR("Received SUSPEND(" << msg.cntlrName << ")"); + setState(CTState::SUSPENDED); + // TODO: implement something useful + CONTROLSuspendedEvent answer; + answer.cntlrName = msg.cntlrName; + port.send(answer); + break; + } + + case CONTROL_RELEASE: { + CONTROLReleaseEvent msg(event); + LOG_DEBUG_STR("Received RELEASE(" << msg.cntlrName << ")"); + setState(CTState::RELEASE); + doRelease(); + setState(CTState::RELEASED); + CONTROLReleasedEvent answer; + answer.cntlrName = msg.cntlrName; + port.send(answer); + break; + } + + default: + LOG_DEBUG("active_state, default"); + status = GCFEvent::NOT_HANDLED; + break; + } + + return (status); +} + +// +// finished_state(event, port) +// +// Finishing state. +// +GCFEvent::TResult OfflineControl::finished_state(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("active:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: { + GCFTask::stop(); + break; + } + default: + LOG_DEBUG("active_state, default"); + status = GCFEvent::NOT_HANDLED; + break; + } + + return (status); +} + + + + +// +// doPrepare(cntlrName) +// +uint16_t OfflineControl::doClaim(const string& cntlrName) +{ + uint16_t result = CT_RESULT_NO_ERROR; + try + { + string processScope("AC.process"); + string offlineCtrlPrefix(globalParameterSet()->locateModule("OfflineCtrl") + "OfflineCtrl."); + + vector<string> procNames, nodes; + string executable, hostName, startstoptype; + string ldName(getName().c_str()); + + procNames = globalParameterSet()->getStringVector(offlineCtrlPrefix+"ApplCtrl.ACCprocess.name"); + + for(size_t i=0;i<procNames.size();i++) + { + string procName = procNames[i]; + + startstoptype = globalParameterSet()->getString(formatString("%sApplCtrl.%s.startstopType", + offlineCtrlPrefix.c_str(), + procName.c_str())); + executable = globalParameterSet()->getString(formatString("%sApplCtrl.%s.executable", + offlineCtrlPrefix.c_str(), + procName.c_str())); + hostName = globalParameterSet()->getString(formatString("%sApplCtrl.%s.hostname", + offlineCtrlPrefix.c_str(), + procName.c_str())); + nodes = globalParameterSet()->getStringVector(formatString("%sApplCtrl.%s.nodes", + offlineCtrlPrefix.c_str(), + procName.c_str())); + itsProcessDependencies[procName] = globalParameterSet()->getStringVector(formatString("%sApplCtrl.%s.depends", + offlineCtrlPrefix.c_str(), + procName.c_str())); + + CEPApplicationManagerPtr accClient(new CEPApplicationManager(*this, procName)); + itsCepApplications[procName] = accClient; + + ACC::APS::ParameterSet params; + params.clear(); + params.replace("AC.application", cntlrName); + // import the ApplCtrl section + params.adoptCollection(globalParameterSet()->makeSubset(offlineCtrlPrefix+"ApplCtrl", "AC")); + // import the <procname> section + params.adoptCollection(globalParameterSet()->makeSubset(offlineCtrlPrefix+procName, procName)); + // import the OLAP section + params.adoptCollection(globalParameterSet()->makeSubset(offlineCtrlPrefix+"OLAP", "OLAP")); + + // add some keys to cope with the differences between the OTDB and ACC + params.replace("AC.resultfile", formatString("./ACC-%s_%s_result.param", cntlrName.c_str(),procName.c_str())); + params.replace("AC.process[0].count","1"); + params.replace("AC.application",procName); + params.replace("AC.process[1].ID",procName); + params.replace("AC.hostname",hostName); + params.replace(formatString("%s.%s[0].startstoptype",procName.c_str(),procName.c_str()),startstoptype); + params.replace(formatString("%s.%s[0].executable",procName.c_str(),procName.c_str()),executable); + + // create nodelist + int nodeIndex=1; + for(vector<string>::iterator it=nodes.begin();it!=nodes.end();++it) + { + params.replace(formatString("AC.%s[%d].node",procName.c_str(),nodeIndex++),*it); + } + itsCepAppParams[procName] = params; + } + } + catch(APSException &) + { + // key not found. skip + result = CT_RESULT_UNSPECIFIED; + } + return result; +} + +// +// doPrepare(cntlrName) +// +uint16_t OfflineControl::doPrepare(const string& cntlrName) +{ + uint16_t result = CT_RESULT_NO_ERROR; + + try + { + map<string, ACC::APS::ParameterSet>::iterator it; + for(it = itsCepAppParams.begin(); it != itsCepAppParams.end();++it) + { + // only start processes that do not depend on other processes + // other process will start once the processes they depend on have finished + if(itsProcessDependencies[it->first].size() == 0) + { + prepareProcess(cntlrName, it->first, to_time_t(itsStartTime)); + } + } + } + catch(APSException &) + { + // key not found. skip + result = CT_RESULT_UNSPECIFIED; + } + return result; +} + +// +// _prepareProcess(procName, startTime) +// +void OfflineControl::prepareProcess(const string& cntlrName, const string& procName, const time_t startTime) +{ + map<string, ACC::APS::ParameterSet>::iterator it = itsCepAppParams.find(procName); + if(it != itsCepAppParams.end()) + { + string procName = it->second.getString("AC.process[1].ID"); + string hostName = it->second.getString("AC.hostname"); + string paramFileName(formatString("ACC-%s_%s.param", cntlrName.c_str(),procName.c_str())); + it->second.writeFile(paramFileName); + + // schedule all ACC commands + time_t initTime = startTime - it->second.getTime("AC.timeout_init"); + time_t defineTime = initTime - it->second.getTime("AC.timeout_define") - + it->second.getTime("AC.timeout_startup"); + time_t bootTime = defineTime - it->second.getTime("AC.timeout_createsubsets"); + time_t now = time(0); + time_t stopTime = to_time_t(itsStopTime); + LOG_DEBUG(formatString("%d now %s time %d", now, ctime(&now), time(0))); + LOG_DEBUG(formatString("%d boot %s", bootTime, ctime(&bootTime))); + LOG_DEBUG(formatString("%d define %s", defineTime, ctime(&defineTime))); + LOG_DEBUG(formatString("%d init %s", initTime, ctime(&initTime))); + LOG_DEBUG(formatString("%d start %s", startTime, ctime(&startTime))); + LOG_DEBUG(formatString("%d stop %s", stopTime, ctime(&stopTime))); + + if (now > bootTime) + { + APLCommon::APLUtilities::remoteCopy(paramFileName,hostName,LOFAR_SHARE_LOCATION); + LOG_WARN("Cannot guarantee all CEP processes are started in time."); + } + else + { + CEPApplicationManagerPtr cepAppPtr = itsCepApplications[procName]; + if(NULL != cepAppPtr) + { + switch (cepAppPtr->getLastOkCmd()) + { + case ACCmdNone: + cepAppPtr->boot(bootTime, paramFileName); + break; + + case ACCmdBoot: + cepAppPtr->define(defineTime); + break; + + case ACCmdDefine: + case ACCmdInit: + case ACCmdRun: + cepAppPtr->recover(0, "snapshot-DB"); + break; + + default: + assert(0); + break; + } + } + APLCommon::APLUtilities::remoteCopy(paramFileName,hostName,LOFAR_SHARE_LOCATION); + } + } +} + +// +// doRelease() +// +void OfflineControl::doRelease(void) +{ + try + { + map<string, ACC::APS::ParameterSet>::iterator it; + for(it = itsCepAppParams.begin(); it != itsCepAppParams.end();++it) + { + string hostName, remoteFile, resultFile, procName; + hostName = it->second.getString("AC.hostname"); + procName = it->second.getString("AC.process[1].ID"); + resultFile = formatString("ACC-%s_%s_result.param", getName().c_str(),procName.c_str()); + remoteFile = string(LOFAR_SHARE_LOCATION) + string("/") + resultFile; + APLCommon::APLUtilities::copyFromRemote(hostName,remoteFile,resultFile); + itsResultParams.adoptFile(resultFile); + // itsResultParams.replace(KVpair(formatString("%s.quality", getName().c_str()), (int) _qualityGuard.getQuality())); + if (!itsResultParams.isDefined(formatString("%s.faultyNodes", getName().c_str()))) + { + itsResultParams.add(formatString("%s.faultyNodes", getName().c_str()), ""); + } + itsResultParams.writeFile(formatString("%s_result.param", getName().c_str())); + } + } + catch(...) + { + } + map<string, CEPApplicationManagerPtr>::iterator it; + for(it = itsCepApplications.begin();it != itsCepApplications.end();++it) + { + it->second->quit(0); + } +} + +// +// finishController +// +void OfflineControl::finishController(uint16_t /*result*/) +{ + setState(CTState::RELEASE); + doRelease(); + setState(CTState::RELEASED); + LOG_DEBUG ("Going to finished state"); + TRAN(OfflineControl::finished_state); // go to next state. +} + +// +// _connectedHandler(port) +// +void OfflineControl::_connectedHandler(GCFPortInterface& /*port*/) +{ +} + +// +// _disconnectedHandler(port) +// +void OfflineControl::_disconnectedHandler(GCFPortInterface& port) +{ + port.close(); +} + +void OfflineControl::appBooted(const string& procName, uint16 result) +{ + LOG_INFO_STR("appBooted from " << procName); + if (result == (AcCmdMaskOk | AcCmdMaskScheduled)) + { + time_t startTime = to_time_t(itsStartTime); + time_t initTime = startTime - itsCepAppParams[0].getTime("AC.timeout_init"); + time_t defineTime = initTime - itsCepAppParams[0].getTime("AC.timeout_define") - + itsCepAppParams[0].getTime("AC.timeout_startup"); + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->define(defineTime); + } + } + else if (result == 0) // Error + { + LOG_ERROR("Error in ACC. Stops CEP application and releases Offline Control."); + finishController(CT_RESULT_UNSPECIFIED); + } +} + +void OfflineControl::appDefined(const string& procName, uint16 result) +{ + LOG_INFO_STR("appDefined from " << procName); + if (result == (AcCmdMaskOk | AcCmdMaskScheduled)) + { + time_t startTime = to_time_t(itsStartTime); + time_t initTime = startTime - itsCepAppParams[0].getTime("AC.timeout_init"); + + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->init(initTime); + } + } + else if (result == 0) // Error + { + LOG_ERROR("Error in ACC. Stops CEP application and releases VB."); + finishController(CT_RESULT_UNSPECIFIED); + } +} + +void OfflineControl::appInitialized(const string& procName, uint16 result) +{ + LOG_INFO_STR("appInitialized from " << procName); + if (result == AcCmdMaskOk) + { + // _doStateTransition(LOGICALDEVICE_STATE_SUSPENDED); + } + else if (result == (AcCmdMaskOk | AcCmdMaskScheduled)) + { + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->run(to_time_t(itsStartTime)); + } + } + else if (result == 0) // Error + { + LOG_ERROR("Error in ACC. Stops CEP application and releases VB."); + finishController(CT_RESULT_UNSPECIFIED); + } +} + +void OfflineControl::appRunDone(const string& procName, uint16 result) +{ + LOG_INFO_STR("appRunDone from " << procName); + if (result == (AcCmdMaskOk | AcCmdMaskScheduled)) + { + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->quit(to_time_t(itsStopTime)); + } + } + else if (result == AcCmdMaskOk) + { + // Run done. Check if processes depend on this process. + map<string, vector<string> >::iterator it; + for(it = itsProcessDependencies.begin(); it != itsProcessDependencies.end();++it) + { + if(it->second.size() > 0) + { + for(vector<string>::iterator dIt = it->second.begin(); dIt != it->second.end(); ++dIt) + { + if((*dIt) == procName) + { + // This process depends on the process that just finished + // Remove the process from the dependencies list. + it->second.erase(dIt); + // If the list is empty now, the new process can be started + if(it->second.size() == 0) + { + // start the process in 5 seconds + prepareProcess(itsCntlrName,it->first,time(0)+5); + } + } + } + } + } + } + else if (result == 0) // Error + { + LOG_ERROR("Error in ACC. Stops CEP application and releases VB."); + finishController(CT_RESULT_UNSPECIFIED); + } +} + +void OfflineControl::appPaused(const string& procName, uint16 /*result*/) +{ + LOG_INFO_STR("appPaused from " << procName); +} + +void OfflineControl::appQuitDone(const string& procName, uint16 result) +{ + LOG_INFO_STR("appQuitDone from " << procName); + if (result == (AcCmdMaskOk | AcCmdMaskScheduled)) + { + //_qualityGuard.stopMonitoring(); // not in this increment + } + else + { + finishController(CT_RESULT_NO_ERROR); + } +} + +void OfflineControl::appSnapshotDone(const string& procName, uint16 /*result*/) +{ + LOG_INFO_STR("appSnapshotDone from " << procName); + time_t rsto(0); + try + { + rsto = globalParameterSet()->getTime("rescheduleTimeOut"); + } + catch (...) {} + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->pause(0, rsto, "condition"); + } +} + +void OfflineControl::appRecovered(const string& procName, uint16 /*result*/) +{ + LOG_INFO_STR("appRecovered from " << procName); + + time_t startTime = to_time_t(itsStartTime); + time_t reinitTime = startTime - itsCepAppParams[0].getTime("AC.timeout_reinit"); + + string paramFileName(formatString("ACC-%s.param", getName().c_str())); + + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->reinit(reinitTime, paramFileName); + } +} + +void OfflineControl::appReinitialized(const string& procName, uint16 result) +{ + LOG_INFO_STR("appReinitialized from " << procName); + if (result == AcCmdMaskOk) + { + // _doStateTransition(LOGICALDEVICE_STATE_SUSPENDED); + } + else if (result == (AcCmdMaskOk | AcCmdMaskScheduled)) + { + map<string,CEPApplicationManagerPtr>::iterator it = itsCepApplications.find(procName); + if(it != itsCepApplications.end()) + { + it->second->run(to_time_t(itsStartTime)); + } + } +} + +void OfflineControl::appReplaced(const string& procName, uint16 /*result*/) +{ + LOG_INFO_STR("appReplaced from " << procName); +} + +string OfflineControl::appSupplyInfo(const string& procName, const string& keyList) +{ + LOG_INFO_STR("appSupplyInfo from " << procName); + string ret(keyList); + return ret; +} + +void OfflineControl::appSupplyInfoAnswer(const string& procName, const string& answer) +{ + LOG_INFO_STR("Answer from " << procName << ": " << answer); +} + + +}; // CEPCU +}; // LOFAR diff --git a/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.h b/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.h new file mode 100644 index 00000000000..7c3a477b86f --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.h @@ -0,0 +1,154 @@ +//# OfflineControl.h: Controller for the OfflineControl +//# +//# Copyright (C) 2006 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef OFFLINECONTROL_H +#define OFFLINECONTROL_H + +//# Includes +#include <boost/shared_ptr.hpp> + +//# GCF Includes +#include <GCF/PAL/GCF_MyPropertySet.h> +#include <GCF/TM/GCF_Port.h> +#include <GCF/TM/GCF_ITCPort.h> +#include <GCF/TM/GCF_TimerPort.h> +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Event.h> + +//# local includes +#include <APL/APLCommon/PropertySetAnswerHandlerInterface.h> +#include <APL/APLCommon/PropertySetAnswer.h> +#include <APL/APLCommon/APLCommonExceptions.h> +#include <APL/APLCommon/Controller_Protocol.ph> +#include <APL/APLCommon/ParentControl.h> +#include <APL/APLCommon/CTState.h> + +#include <CEPApplicationManager.h> + +//# Common Includes +#include <Common/lofar_string.h> +#include <Common/lofar_vector.h> +#include <Common/lofar_datetime.h> +#include <Common/LofarLogger.h> + +//# ACC Includes +#include <APS/ParameterSet.h> + +// forward declaration + +namespace LOFAR { + namespace CEPCU { + +using GCF::TM::GCFTimerPort; +using GCF::TM::GCFITCPort; +using GCF::TM::GCFPort; +using GCF::TM::GCFEvent; +using GCF::TM::GCFPortInterface; +using GCF::TM::GCFTask; +using APLCommon::ParentControl; + + +class OfflineControl : public GCFTask, + public APLCommon::PropertySetAnswerHandlerInterface, + public CEPApplicationManagerInterface +{ +public: + explicit OfflineControl(const string& cntlrName); + ~OfflineControl(); + + // PropertySetAnswerHandlerInterface method + void handlePropertySetAnswer(GCFEvent& answer); + + // During the initial state all connections with the other programs are made. + GCFEvent::TResult initial_state (GCFEvent& e, + GCFPortInterface& p); + + // Normal control mode. + GCFEvent::TResult active_state (GCFEvent& e, + GCFPortInterface& p); + + // Finishing mode. + GCFEvent::TResult finished_state(GCFEvent& event, + GCFPortInterface& port); + +protected: // implemenation of abstract CEPApplicationManagerInterface methods + void appBooted(const string& procName, uint16 result); + void appDefined(const string& procName, uint16 result); + void appInitialized(const string& procName, uint16 result); + void appRunDone(const string& procName, uint16 result); + void appPaused(const string& procName, uint16 result); + void appQuitDone(const string& procName, uint16 result); + void appSnapshotDone(const string& procName, uint16 result); + void appRecovered(const string& procName, uint16 result); + void appReinitialized(const string& procName, uint16 result); + void appReplaced(const string& procName, uint16 result); + string appSupplyInfo(const string& procName, const string& keyList); + void appSupplyInfoAnswer(const string& procName, const string& answer); + +private: + // avoid defaultconstruction and copying + OfflineControl(); + OfflineControl(const OfflineControl&); + OfflineControl& operator=(const OfflineControl&); + + uint16_t doClaim(const string& cntlrName); + uint16_t doPrepare(const string& cntlrName); + void prepareProcess(const string& cntlrName, const string& procName, const time_t startTime); + void doRelease(); + void finishController(uint16_t result); + void _connectedHandler(GCFPortInterface& port); + void _disconnectedHandler(GCFPortInterface& port); + void setState(CTState::CTstateNr newState); + + typedef boost::shared_ptr<GCF::PAL::GCFMyPropertySet> GCFMyPropertySetPtr; + typedef boost::shared_ptr<CEPApplicationManager> CEPApplicationManagerPtr; + + APLCommon::PropertySetAnswer itsPropertySetAnswer; + GCFMyPropertySetPtr itsPropertySet; + bool itsPropertySetInitialized; + + // pointer to parent control task + ParentControl* itsParentControl; + GCFITCPort* itsParentPort; + + GCFTimerPort* itsTimerPort; + + map<string, CEPApplicationManagerPtr> itsCepApplications; + map<string, ACC::APS::ParameterSet> itsCepAppParams; + ACC::APS::ParameterSet itsResultParams; + map<string, vector<string> > itsProcessDependencies; + + CTState::CTstateNr itsState; + + // ParameterSet variables + string itsTreePrefix; + uint32 itsInstanceNr; + ptime itsStartTime; + ptime itsStopTime; + uint32 itsClaimPeriod; + uint32 itsPreparePeriod; + string itsCntlrName; +}; + + };//CEPCU +};//LOFAR +#endif diff --git a/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.log_prop.in b/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.log_prop.in new file mode 100644 index 00000000000..fc002f4164c --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/OfflineControl.log_prop.in @@ -0,0 +1,20 @@ +# add your custom loggers and appenders here +# + +log4cplus.rootLogger=DEBUG, STDOUT, FILE + +log4cplus.logger.TRC=TRACE2 +log4cplus.additivity.TRC=FALSE + +log4cplus.appender.STDOUT=log4cplus::ConsoleAppender +log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout +log4cplus.appender.STDOUT.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S.%q} %-5p %c{9} - %m [%.25l]%n +log4cplus.appender.STDOUT.logToStdErr=true + +log4cplus.appender.FILE=log4cplus::RollingFileAppender +log4cplus.appender.FILE.File=../log/OfflineControl.log +log4cplus.appender.FILE.MaxFileSize=5MB +log4cplus.appender.FILE.MaxBackupIndex=5 +log4cplus.appender.FILE.layout=log4cplus::PatternLayout +log4cplus.appender.FILE.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%.25l]%n + diff --git a/MAC/APL/CEPCU/src/OfflineControl/OfflineControlDefines.h b/MAC/APL/CEPCU/src/OfflineControl/OfflineControlDefines.h new file mode 100644 index 00000000000..fb7368cbc1a --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/OfflineControlDefines.h @@ -0,0 +1,43 @@ +//# OfflineControlDefines.h: preprocessor definitions of various constants +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef OFFLINECONTROLDEFINES_H +#define OFFLINECONTROLDEFINES_H + +namespace LOFAR { + namespace CEPCU { + +#define ONC_TASKNAME "OfflineCtrl" + +#define ONC_PROPSET_NAME "LOFAR_ObsSW_ObsCtrl%d_OfflineCtrl" +#define ONC_PROPSET_TYPE "OfflineCtrl" +#define ONC_OBSERVATIONSTATE "observationState" + +// next lines should be defined somewhere in Common. +#define PVSSNAME_FSM_STATE "state" +#define PVSSNAME_FSM_ERROR "error" + + +}; // MCU +}; // LOFAR + +#endif diff --git a/MAC/APL/CEPCU/src/OfflineControl/OfflineControlMain.cc b/MAC/APL/CEPCU/src/OfflineControl/OfflineControlMain.cc new file mode 100644 index 00000000000..d8f1e2e3c14 --- /dev/null +++ b/MAC/APL/CEPCU/src/OfflineControl/OfflineControlMain.cc @@ -0,0 +1,52 @@ +//# OfflineControlMain.cc: Main entry for the OfflineControl controller. +//# +//# Copyright (C) 2006 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ +//# +#include <lofar_config.h> +#include <Common/LofarLogger.h> + +#include "OfflineControl.h" + +using namespace LOFAR::GCF::TM; +using namespace LOFAR::CEPCU; + +int main(int argc, char* argv[]) +{ + // args: cntlrname + if(argc < 2) + { + printf("Unexpected number of arguments: %d\n",argc); + printf("%s usage: %s <controller name>\n",argv[0],argv[0]); + exit(-1); + } + GCFTask::init(argc, argv); + + ParentControl* pc = ParentControl::instance(); + pc->start(); // make initial transition + + OfflineControl ofc(argv[1]); + ofc.start(); // make initial transition + + GCFTask::run(); + + return 0; +} + -- GitLab