diff --git a/MAC/APL/StationCU/src/BeamControl/BeamControl.cc b/MAC/APL/StationCU/src/BeamControl/BeamControl.cc index ae74dc1314da9d19dbc1560fac01acbafcd60e41..83e4e519d642c7400e170801e68ad0a131d4e290 100644 --- a/MAC/APL/StationCU/src/BeamControl/BeamControl.cc +++ b/MAC/APL/StationCU/src/BeamControl/BeamControl.cc @@ -70,7 +70,6 @@ BeamControl::BeamControl(const string& cntlrName) : 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"); @@ -80,8 +79,11 @@ BeamControl::BeamControl(const string& cntlrName) : getString("Observation.startTime")); itsStopTime = time_from_string(globalParameterSet()-> getString("Observation.stopTime")); - itsClaimPeriod = globalParameterSet()->getTime ("Observation.claimPeriod"); - itsPreparePeriod = globalParameterSet()->getTime ("Observation.preparePeriod"); +// itsClaimPeriod = globalParameterSet()->getTime ("Observation.claimPeriod"); +// itsPreparePeriod = globalParameterSet()->getTime ("Observation.preparePeriod"); + + // Instruct codeloggingProcessor + LOG_INFO_STR("MACProcessScope: " << itsTreePrefix + cntlrName); // attach to parent control task itsParentControl = ParentControl::instance(); @@ -225,8 +227,8 @@ GCFEvent::TResult BeamControl::initial_state(GCFEvent& event, case F_INIT: { // Get access to my own propertyset. - LOG_DEBUG ("Activating PropertySet"); string propSetName(createPropertySetName(PSN_BEAM_CTRL, getName())); + LOG_DEBUG_STR ("Activating PropertySet" << propSetName); itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(), PST_BEAM_CTRL, PS_CAT_TEMPORARY, @@ -258,15 +260,15 @@ GCFEvent::TResult BeamControl::initial_state(GCFEvent& event, break; case F_DISCONNECTED: + case F_CLOSED: + case F_EXIT: break; 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); + sendControlResult(port, CONTROL_CONNECTED, msg.cntlrName, CT_RESULT_NO_ERROR); LOG_DEBUG ("Going to started state"); TRAN(BeamControl::started_state); // go to next state. @@ -274,10 +276,10 @@ GCFEvent::TResult BeamControl::initial_state(GCFEvent& event, } default: - LOG_DEBUG_STR ("initial, default"); - status = GCFEvent::NOT_HANDLED; + status = _defaultEventHandler(event, port); break; - } + } + return (status); } @@ -296,12 +298,13 @@ GCFEvent::TResult BeamControl::started_state(GCFEvent& event, GCFPortInterface& switch (event.signal) { case F_ENTRY: { // update PVSS - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("started")); +// itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("started")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); break; } case F_INIT: + case F_EXIT: break; case F_CONNECTED: { @@ -324,6 +327,9 @@ GCFEvent::TResult BeamControl::started_state(GCFEvent& event, GCFPortInterface& break; } + case F_CLOSED: + break; + case F_TIMER: // GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); LOG_DEBUG ("Trying to reconnect to BeamServer"); @@ -340,9 +346,12 @@ GCFEvent::TResult BeamControl::started_state(GCFEvent& event, GCFPortInterface& break; } + case CONTROL_QUIT: + TRAN(BeamControl::quiting_state); + break; + default: - LOG_DEBUG("started, default"); - status = GCFEvent::NOT_HANDLED; + status = _defaultEventHandler(event, port); break; } @@ -363,12 +372,13 @@ GCFEvent::TResult BeamControl::claimed_state(GCFEvent& event, GCFPortInterface& switch (event.signal) { case F_ENTRY: { // update PVSS - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("claimed")); +// itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("claimed")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); break; } case F_INIT: + case F_EXIT: break; case F_DISCONNECTED: { @@ -380,15 +390,22 @@ GCFEvent::TResult BeamControl::claimed_state(GCFEvent& event, GCFPortInterface& break; } + case F_CLOSED: + break; + // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- case CONTROL_PREPARE: { CONTROLPrepareEvent msg(event); LOG_DEBUG_STR("Received PREPARE(" << msg.cntlrName << ")"); setState(CTState::PREPARE); - doPrepare(msg.cntlrName); // will result in BS_BEAMALLOCACK event + doPrepare(); // will result in BS_BEAMALLOCACK event break; } + case CONTROL_QUIT: + TRAN(BeamControl::quiting_state); + break; + // -------------------- EVENTS RECEIVED FROM BEAMSERVER -------------------- case BS_BEAMALLOCACK: { BSBeamallocackEvent msg(event); @@ -398,18 +415,19 @@ GCFEvent::TResult BeamControl::claimed_state(GCFEvent& event, GCFPortInterface& LOG_DEBUG("Beam allocated, going to active state"); TRAN(BeamControl::active_state); } + else { + LOG_WARN_STR("Beamallocation failed with error " << result << + ", staying in CLAIMED mode"); + setState(CTState::CLAIMED); + } LOG_DEBUG_STR("Sending PREPARED(" << getName() << "," << result << ") event"); - CONTROLPreparedEvent answer; - answer.cntlrName = getName(); - answer.result = result; - itsParentPort->send(answer); + sendControlResult(*itsParentPort, CONTROL_PREPARED, getName(), result); break; } default: - LOG_DEBUG("claimed, default"); - status = GCFEvent::NOT_HANDLED; + status = _defaultEventHandler(event, port); break; } @@ -430,12 +448,13 @@ GCFEvent::TResult BeamControl::active_state(GCFEvent& event, GCFPortInterface& p switch (event.signal) { case F_ENTRY: { // update PVSS - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active")); +// itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); break; } case F_INIT: + case F_EXIT: break; case F_DISCONNECTED: { @@ -446,6 +465,9 @@ GCFEvent::TResult BeamControl::active_state(GCFEvent& event, GCFPortInterface& p TRAN(BeamControl::started_state); break; } + + case F_CLOSED: + break; // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- @@ -460,21 +482,17 @@ GCFEvent::TResult BeamControl::active_state(GCFEvent& event, GCFPortInterface& p CONTROLResumeEvent msg(event); LOG_DEBUG_STR("Received RESUME(" << msg.cntlrName << ")"); setState(CTState::RESUME); - // TODO: implement something useful - CONTROLResumedEvent answer; - answer.cntlrName = msg.cntlrName; - port.send(answer); + sendControlResult(port, CONTROL_RESUMED, msg.cntlrName, CT_RESULT_NO_ERROR); + setState(CTState::RESUMED); break; } case CONTROL_SUSPEND: { CONTROLSuspendEvent msg(event); LOG_DEBUG_STR("Received SUSPEND(" << msg.cntlrName << ")"); + setState(CTState::SUSPEND); + sendControlResult(port, CONTROL_SUSPENDED, msg.cntlrName, CT_RESULT_NO_ERROR); setState(CTState::SUSPENDED); - // TODO: implement something useful - CONTROLSuspendedEvent answer; - answer.cntlrName = msg.cntlrName; - port.send(answer); break; } @@ -482,31 +500,98 @@ GCFEvent::TResult BeamControl::active_state(GCFEvent& event, GCFPortInterface& p CONTROLReleaseEvent msg(event); LOG_DEBUG_STR("Received RELEASED(" << msg.cntlrName << ")"); setState(CTState::RELEASE); - doRelease(event); - setState(CTState::RELEASED); - CONTROLReleasedEvent answer; - answer.cntlrName = msg.cntlrName; - port.send(answer); - LOG_DEBUG("Released beam going back to 'claimed' mode"); - TRAN(BeamControl::claimed_state); + doRelease(); // results in BS_BEAMFREEACK break; } - case CONTROL_QUIT: { - CONTROLQuitEvent msg(event); - LOG_DEBUG("Received QUIT event, going down"); - stop(); + case CONTROL_QUIT: + TRAN(BeamControl::quiting_state); + break; + + // -------------------- EVENTS RECEIVED FROM BEAMSERVER -------------------- + case BS_BEAMFREEACK: { + if (!handleBeamFreeAck(event)) { + LOG_DEBUG("Error in freeing beam, staying in active_state"); + sendControlResult(*itsParentPort, CONTROL_RELEASED, getName(), + CT_RESULT_BEAMFREE_FAILED); + } + else { + LOG_DEBUG("Released beam going back to 'claimed' mode"); + setState(CTState::RELEASED); + sendControlResult(*itsParentPort, CONTROL_RELEASED, getName(), + CT_RESULT_NO_ERROR); + TRAN(BeamControl::claimed_state); + } } break; - // -------------------- EVENTS RECEIVED FROM BEAMSERVER -------------------- - case BS_BEAMFREEACK: - handleBeamFreeAck(event); + default: + status = _defaultEventHandler(event, port); break; + } + + return (status); +} + +// +// quiting_state(event, port) +// +// Quiting: send FINISH, wait for answer max 5 seconds, stop +// +GCFEvent::TResult BeamControl::quiting_state(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("quiting:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: { + // update PVSS + setState(CTState::FINISH); +// itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("quiting")); + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + itsBeamServer->close(); + break; + } + + case F_INIT: + case F_EXIT: + break; + + case F_DISCONNECTED: + port.close(); + // fall through!!! + case F_CLOSED: { + ASSERTSTR (&port == itsBeamServer, + "F_DISCONNECTED event from port " << port.getName()); + LOG_DEBUG("Connection with BeamServer down, sending FINISH"); + CONTROLFinishEvent request; + request.cntlrName = getName(); + request.result = CT_RESULT_NO_ERROR; + itsParentPort->send(request); + itsTimerPort->setTimer(5.0); // wait max 5 seconds for response + break; + } + + case F_TIMER: + LOG_DEBUG("Timeout on reception of FINISHED event, too bad."); + setState(CTState::FINISHED); + stop(); + break; + + // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- + + case CONTROL_FINISHED: { + CONTROLFinishedEvent msg(event); + LOG_DEBUG_STR("Received FINISHED(" << msg.cntlrName << ")"); + LOG_DEBUG_STR("Normal shutdown of " << getName()); + setState(CTState::FINISHED); + stop(); + break; + } default: - LOG_DEBUG("active_state, default"); - status = GCFEvent::NOT_HANDLED; + status = _defaultEventHandler(event, port); break; } @@ -515,12 +600,10 @@ GCFEvent::TResult BeamControl::active_state(GCFEvent& event, GCFPortInterface& p // -// doPrepare(cntlrName) +// doPrepare() // -void BeamControl::doPrepare(const string& cntlrName) +void BeamControl::doPrepare() { - // TODO use parameterset of 'cntlrname' when being shared controller - string subbandList(globalParameterSet()->getString("Observation.subbandList")); string beamletList(globalParameterSet()->getString("Observation.beamletList")); LOG_DEBUG_STR("subbandlist:" << subbandList); @@ -611,7 +694,7 @@ uint16 BeamControl::handleBeamAllocAck(GCFEvent& event) // // doRelease(event) // -void BeamControl::doRelease(GCFEvent& event) +void BeamControl::doRelease() { BSBeamfreeEvent beamFreeEvent; beamFreeEvent.handle = itsBeamID; @@ -632,12 +715,61 @@ bool BeamControl::handleBeamFreeAck(GCFEvent& event) return (true); } +// _defaultEventHandler(event, port) +// +GCFEvent::TResult BeamControl::_defaultEventHandler(GCFEvent& event, + GCFPortInterface& port) +{ + CTState cts; + LOG_DEBUG_STR("Received " << evtstr(event) << " in state " << cts.name(itsState) + << ". DEFAULT handling."); + + GCFEvent::TResult result(GCFEvent::NOT_HANDLED); + + switch (event.signal) { + case CONTROL_CONNECT: + case CONTROL_RESYNC: + case CONTROL_SCHEDULE: // we should do something with this + case CONTROL_CLAIM: + case CONTROL_PREPARE: + case CONTROL_RESUME: + case CONTROL_SUSPEND: + case CONTROL_RELEASE: + case CONTROL_FINISH: + if (sendControlResult(port, event.signal, getName(), CT_RESULT_NO_ERROR)) { + result = GCFEvent::HANDLED; + } + break; + + case CONTROL_CONNECTED: + case CONTROL_RESYNCED: + case CONTROL_SCHEDULED: + case CONTROL_CLAIMED: + case CONTROL_PREPARED: + case CONTROL_RESUMED: + case CONTROL_SUSPENDED: + case CONTROL_RELEASED: + case CONTROL_FINISHED: + result = GCFEvent::HANDLED; + break; + } + + if (result == GCFEvent::NOT_HANDLED) { + LOG_WARN_STR("Event " << evtstr(event) << " NOT handled in state " << + cts.name(itsState)); + } + + return (result); +} + + // _connectedHandler(port) // -void BeamControl::_connectedHandler(GCFPortInterface& port) +void BeamControl::_connectedHandler(GCFPortInterface& /*port*/) { } + // // _disconnectedHandler(port) // diff --git a/MAC/APL/StationCU/src/BeamControl/BeamControl.h b/MAC/APL/StationCU/src/BeamControl/BeamControl.h index eee85fe6869a50066df966155b5d13317ef2da53..dedfe74ec641ecf56cec46d32452160e493fa255 100644 --- a/MAC/APL/StationCU/src/BeamControl/BeamControl.h +++ b/MAC/APL/StationCU/src/BeamControl/BeamControl.h @@ -83,6 +83,8 @@ public: GCFEvent::TResult claimed_state (GCFEvent& e, GCFPortInterface& p); // Normal control mode, beam is active GCFEvent::TResult active_state (GCFEvent& e, GCFPortInterface& p); + // Quiting, shutdown connections, send FINISH and quit + GCFEvent::TResult quiting_state (GCFEvent& e, GCFPortInterface& p); private: // avoid defaultconstruction and copying @@ -91,13 +93,14 @@ private: BeamControl& operator=(const BeamControl&); int32 convertDirection(const string& typeName); - void doPrepare(const string& cntlrName); + void doPrepare(); uint16 handleBeamAllocAck(GCFEvent& event); bool handleBeamFreeAck(GCFEvent& event); - void doRelease(GCFEvent& event); + void doRelease(); void _connectedHandler(GCFPortInterface& port); void _disconnectedHandler(GCFPortInterface& port); void setState(CTState::CTstateNr newState); + GCFEvent::TResult _defaultEventHandler(GCFEvent& event, GCFPortInterface& port); typedef boost::shared_ptr<GCF::PAL::GCFMyPropertySet> GCFMyPropertySetPtr; @@ -105,19 +108,6 @@ private: GCFMyPropertySetPtr itsPropertySet; bool itsPropertySetInitialized; -#if 0 - // Administration of the BeamControllers - typedef struct { - OTDB::treeIDType treeID; // tree in the OTDB - GCFTCPPort* port; // TCP connection with controller - uint16 state; // state the controller has - } ObsCntlr_t; - - // Map with all active BeamControllers. - map<GCFTCPPort*, ObsCntlr_t> itsObsCntlrMap; - vector<GCFTCPPort*> itsObsCntlrPorts; -#endif - // pointer to parent control task ParentControl* itsParentControl; GCFITCPort* itsParentPort; diff --git a/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc b/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc index 1911fc4a980513eda0f5863c95e6e6c8d6baf4de..a08748e8e9df112eb2822bf0f7bd0e2632673008 100644 --- a/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc +++ b/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc @@ -21,19 +21,19 @@ //# $Id$ #include <lofar_config.h> #include <Common/LofarLogger.h> -#include <Common/LofarLocators.h> +#include <Common/lofar_datetime.h> -#include <boost/shared_array.hpp> -#include <APS/ParameterSet.h> +//#include <boost/shared_array.hpp> +//#include <APS/ParameterSet.h> #include <GCF/GCF_PVTypes.h> -#include <GCF/PAL/GCF_PVSSInfo.h> -#include <GCF/Utils.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/APLCommonExceptions.h> +//#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/ControllerDefines.h> #include <APL/APLCommon/StationInfo.h> #include <APL/CAL_Protocol/CAL_Protocol.ph> @@ -62,18 +62,20 @@ CalibrationControl::CalibrationControl(const string& cntlrName) : itsParentPort (0), itsTimerPort (0), itsCalServer (0), -// itsState (CTState::NOSTATE) - itsObsMap (), - itsPropSetAvailTimer(0) + itsState (CTState::NOSTATE) { 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(itsTreePrefix + ".instanceNr"); - itsStartTime = globalParameterSet()->getTime (itsTreePrefix + ".starttime"); - itsStopTime = globalParameterSet()->getTime (itsTreePrefix + ".stoptime"); + itsInstanceNr = globalParameterSet()->getUint32("_instanceNr"); + itsObsPar = Observation(globalParameterSet()); + // Instruct CodeLoggingProcessor LOG_INFO_STR("MACProcessScope: " << itsTreePrefix + cntlrName); // attach to parent control task @@ -120,7 +122,7 @@ CalibrationControl::~CalibrationControl() // void CalibrationControl::setState(CTState::CTstateNr newState) { -// itsState = newState; + itsState = newState; if (itsPropertySet) { CTState cts; @@ -147,45 +149,6 @@ int32 CalibrationControl::convertFilterSelection(const string& filterselection) return (1); } -// -// propertySetsAvailable() -// -// REO: does CC watch every rcu propertyset???? -// -bool CalibrationControl::propertySetsAvailable() -{ - return (true); - - // TODO: calculate m_n_rcus: racks * subracks ... - // uint32 m_n_rcus = 192; - // return (m_rcuFunctionalityMap.size() == m_n_rcus); - -} - -// -// getRCUHardwareNr (propertyname) -// -int32 CalibrationControl::getRCUHardwareNr(const string& propName) -{ - // strip property and systemname, propertyset name remains - int posBegin = propName.find_first_of(":") + 1; - int posEnd = propName.find_last_of("."); - string propertySetName = propName.substr(posBegin,posEnd-posBegin); - - // search in property map. - TRCUMap::iterator it = m_rcuMap.begin(); - TRCUMap::iterator end = m_rcuMap.end(); - while (it != end) { - if (propertySetName == it->second->getScope()) { - return (it->first); - } - ++it; - } - - return (-1); -} - - // // handlePropertySetAnswer(answer) // @@ -205,46 +168,12 @@ void CalibrationControl::handlePropertySetAnswer(GCFEvent& answer) break; } - case F_VGETRESP: { + case F_VGETRESP: + case F_VCHANGEMSG: // check which property changed - GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer); - - // check if it is a functionality - if(strstr(pPropAnswer->pPropName, PROPNAME_FUNCTIONALITY) != 0) { - // add the functionality state to the internal cache - int rcu = getRCUHardwareNr(pPropAnswer->pPropName); - if (rcu >= 0) { - bool functional = ((GCFPVBool*)pPropAnswer->pValue)->getValue(); - m_rcuFunctionalityMap[static_cast<uint16>(rcu)] = functional; - } - } + // GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer); + // TODO: implement something usefull. break; - } - - case F_VCHANGEMSG: { - GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer); - - // check if it is a functionality - if (strstr(pPropAnswer->pPropName, PROPNAME_FUNCTIONALITY) != 0) { - LOG_DEBUG("functionality property changed"); - // add the functionality to the internal cache - int rcu = getRCUHardwareNr(pPropAnswer->pPropName); - if (rcu >= 0) { - bool functional = ((GCFPVBool*)pPropAnswer->pValue)->getValue(); - m_rcuFunctionalityMap[static_cast<uint16>(rcu)] = functional; - LOG_DEBUG(formatString("RCU %d functionality: %s", - rcu, (functional ? "true" : "false"))); - } - // TODO -//TODO if (getLogicalDeviceState() == LOGICALDEVICE_STATE_ACTIVE) { -//TODO // check functionality state of RCU's -//TODO if (!checkQuality()) { -//TODO suspend(LD_RESULT_LOW_QUALITY); -//TODO } -//TODO } - } - break; - } // case F_SUBSCRIBED: GCFPropAnswerEvent pPropName // case F_UNSUBSCRIBED: GCFPropAnswerEvent pPropName @@ -267,7 +196,7 @@ void CalibrationControl::handlePropertySetAnswer(GCFEvent& answer) // // initial_state(event, port) // -// Setup all connections. +// Connect to PVSS and report state back to StartDaemon // GCFEvent::TResult CalibrationControl::initial_state(GCFEvent& event, GCFPortInterface& port) @@ -286,7 +215,7 @@ GCFEvent::TResult CalibrationControl::initial_state(GCFEvent& event, LOG_DEBUG_STR ("Activating PropertySet" << propSetName); itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(), PST_CAL_CTRL, - PS_CAT_PERM_AUTOLOAD, + PS_CAT_TEMPORARY, &itsPropertySetAnswer)); itsPropertySet->enable(); // Wait for timer that is set in PropertySetAnswer on ENABLED event @@ -303,84 +232,71 @@ GCFEvent::TResult CalibrationControl::initial_state(GCFEvent& event, itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); // Start ParentControl task - LOG_DEBUG ("Enabling ParentControl task"); + LOG_DEBUG ("Enabling ParentControl task and wait for my name"); itsParentPort = itsParentControl->registerTask(this); - - // Open connection with CalServer - LOG_DEBUG ("Trying to connect to CalibrationServer"); - itsCalServer->open(); // will result in F_CONN or F_DISCONN - } - else { - // its the disconnected timer - itsCalServer->open(); // will result in F_CONN or F_DISCONN + // results in CONTROL_CONNECT } break; case F_CONNECTED: - if (&port == itsParentPort) { - break; - } - - // CONNECT must be from Calserver. - ASSERTSTR (&port == itsCalServer, - "F_CONNECTED event from port " << port.getName()); - itsTimerPort->cancelAllTimers(); - LOG_DEBUG ("Connected with CalServer, going to operational state"); - TRAN(CalibrationControl::active_state); // go to next state. + ASSERTSTR (&port == itsParentPort, + "F_CONNECTED event from port " << port.getName()); break; case F_DISCONNECTED: - port.close(); - ASSERTSTR (&port == itsCalServer, - "F_DISCONNECTED event from port " << port.getName()); - LOG_DEBUG("Connection with CalServer failed, retry in 2 seconds"); - itsTimerPort->setTimer(2.0); + case F_CLOSED: + case F_EXIT: break; - + + case CONTROL_CONNECT: { + CONTROLConnectEvent msg(event); + LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")"); + setState(CTState::CONNECTED); + sendControlResult(port, CONTROL_CONNECTED, msg.cntlrName, CT_RESULT_NO_ERROR); + + LOG_DEBUG ("Going to started state"); + TRAN(CalibrationControl::started_state); + break; + } + default: - LOG_DEBUG_STR ("initial, default"); - status = GCFEvent::NOT_HANDLED; + status = _defaultEventHandler(event, port); break; } + return (status); } - // -// active_state(event, port) +// started_state(event, port) // -// Normal operation state. +// wait for CLAIM event // -GCFEvent::TResult CalibrationControl::active_state(GCFEvent& event, GCFPortInterface& port) +GCFEvent::TResult CalibrationControl::started_state(GCFEvent& event, + GCFPortInterface& port) { - LOG_DEBUG_STR ("active:" << evtstr(event) << "@" << port.getName()); + LOG_DEBUG_STR ("started:" << evtstr(event) << "@" << port.getName()); GCFEvent::TResult status = GCFEvent::HANDLED; switch (event.signal) { case F_INIT: + case F_EXIT: break; - case F_ENTRY: { + case F_ENTRY: // update PVSS - itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); - -// loadPVSSpropertySets(); // of all RCU boards - // this takes a while so - itsPropSetAvailTimer = itsTimerPort->setTimer(3.0); // check over 3 seconds - break; - } - - case F_ACCEPT_REQ: break; - case F_CONNECTED: + case F_CONNECTED: // CONNECT must be from Calserver. ASSERTSTR (&port == itsCalServer, "F_CONNECTED event from port " << port.getName()); itsTimerPort->cancelAllTimers(); - LOG_DEBUG ("Reconnected with CalServer"); - // TODO: resend all claimes. + LOG_DEBUG ("Connected with CalServer, going to claimed state"); + setState(CTState::CLAIMED); + sendControlResult(*itsParentPort, CONTROL_CLAIMED, getName(), CT_RESULT_NO_ERROR); + TRAN(CalibrationControl::claimed_state); // go to next state. break; case F_DISCONNECTED: @@ -391,137 +307,196 @@ GCFEvent::TResult CalibrationControl::active_state(GCFEvent& event, GCFPortInter itsTimerPort->setTimer(2.0); break; - case F_TIMER: { - GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); - if (timerEvent.id == itsPropSetAvailTimer) { - if (propertySetsAvailable()) { - LOG_DEBUG("PVSS propertySet are active."); - itsPropSetAvailTimer = 0; - } - else { - itsPropSetAvailTimer = itsTimerPort->setTimer(1.0); // check again later - } - } - else { - LOG_DEBUG ("Trying to reconnect to CalServer"); - itsCalServer->open(); // will result in F_CONN or F_DISCONN - } + case F_CLOSED: + break; + + case F_TIMER: + LOG_DEBUG ("Trying to reconnect to CalServer"); + itsCalServer->open(); // will result in F_CONN or F_DISCONN break; - } // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- - case CONTROL_CONNECT: { - CONTROLConnectEvent msg(event); - CONTROLConnectedEvent answer; - answer.cntlrName = msg.cntlrName; - LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")"); - // add observation to list if not already in list - answer.result = addObservation(msg.cntlrName) ? - CT_RESULT_NO_ERROR : CT_RESULT_UNSPECIFIED; - port.send(answer); + case CONTROL_CLAIM: { + CONTROLClaimEvent msg(event); + LOG_DEBUG_STR ("Received CLAIM(" << msg.cntlrName << ")"); + setState(CTState::CLAIM); + LOG_DEBUG ("Trying to connect to CalServer"); + itsCalServer->open(); break; } - case CONTROL_SCHEDULED: { - CONTROLScheduledEvent msg(event); - LOG_DEBUG_STR("Received SCHEDULED(" << msg.cntlrName << ")"); - // TODO: do something usefull with this information! + case CONTROL_QUIT: + TRAN(CalibrationControl::quiting_state); + break; + + default: + status = _defaultEventHandler(event, port); break; } - case CONTROL_CLAIM: { - CONTROLClaimEvent msg(event); - CONTROLClaimedEvent answer; - answer.cntlrName = msg.cntlrName; - LOG_DEBUG_STR("Received CLAIM(" << msg.cntlrName << ")"); - answer.result = handleClaimEvent(msg.cntlrName); - port.send(answer); + return (status); +} + + +// +// claimed_state(event, port) +// +// wait for PREPARE event +// +GCFEvent::TResult CalibrationControl::claimed_state(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("claimed:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + case F_EXIT: + break; + + case F_ENTRY: { + // update PVSS + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); break; } + case F_DISCONNECTED: + port.close(); + ASSERTSTR (&port == itsCalServer, + "F_DISCONNECTED event from port " << port.getName()); + LOG_DEBUG("Connection with CalServer lost, going to reconnect state."); + TRAN(CalibrationControl::started_state); + break; + + case F_CLOSED: + break; + + // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- case CONTROL_PREPARE: { CONTROLPrepareEvent msg(event); LOG_DEBUG_STR("Received PREPARE(" << msg.cntlrName << ")"); - if (!startCalibration(msg.cntlrName)) { // will result in CAL_STARTACK event - CONTROLPreparedEvent answer; // when command was sent. - answer.cntlrName = msg.cntlrName; - answer.result = CT_RESULT_CALSTART_FAILED; - port.send(answer); + setState(CTState::PREPARE); + if (!startCalibration()) { // will result in CAL_STARTACK event + sendControlResult(port, CONTROL_PREPARED, msg.cntlrName, + CT_RESULT_CALSTART_FAILED); + setState(CTState::CLAIMED); } break; } + case CONTROL_QUIT: + TRAN(CalibrationControl::quiting_state); + break; + + // -------------------- EVENTS RECEIVED FROM CALSERVER -------------------- + case CAL_STARTACK: { + CALStartackEvent ack(event); + if (ack.status == SUCCESS || ack.status == ERR_ALREADY_REGISTERED) { + LOG_DEBUG ("Start of calibration was succesful"); + sendControlResult(*itsParentPort, CONTROL_PREPARED, getName(), + CT_RESULT_NO_ERROR); + setState(CTState::PREPARED); + } + else { + LOG_ERROR("Start of calibration failed, staying in CLAIMED mode"); + sendControlResult(*itsParentPort, CONTROL_PREPARED, getName(), + CT_RESULT_CALSTART_FAILED); + setState(CTState::CLAIMED); + } + } + break; + + default: + status = _defaultEventHandler(event, port); + break; + } + + return (status); +} + + +// +// active_state(event, port) +// +// Normal operation state. +// +GCFEvent::TResult CalibrationControl::active_state(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("active:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + case F_EXIT: + case F_CLOSED: + break; + + case F_ENTRY: { + // update PVSS + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + break; + } + + case F_DISCONNECTED: + port.close(); + ASSERTSTR (&port == itsCalServer, + "F_DISCONNECTED event from port " << port.getName()); + LOG_DEBUG("Connection with CalServer lost, going to reconnect"); + TRAN(CalibrationControl::started_state); + break; + + // -------------------- EVENTS RECEIVED FROM PARENT CONTROL -------------------- + case CONTROL_RESUME: { CONTROLResumeEvent msg(event); LOG_DEBUG_STR("Received RESUME(" << msg.cntlrName << ")"); - // TODO: do something here? - CONTROLResumedEvent answer; - answer.cntlrName = msg.cntlrName; - answer.result = CT_RESULT_NO_ERROR; - port.send(answer); + setState(CTState::RESUME); + sendControlResult(port, CONTROL_RESUMED, getName(), CT_RESULT_NO_ERROR); + setState(CTState::RESUMED); break; } case CONTROL_SUSPEND: { CONTROLSuspendEvent msg(event); LOG_DEBUG_STR("Received SUSPEND(" << msg.cntlrName << ")"); - // TODO: do something here? - CONTROLSuspendedEvent answer; - answer.cntlrName = msg.cntlrName; - answer.result = CT_RESULT_NO_ERROR; - port.send(answer); + setState(CTState::SUSPEND); + sendControlResult(port, CONTROL_SUSPENDED, getName(), CT_RESULT_NO_ERROR); + setState(CTState::SUSPENDED); break; } case CONTROL_RELEASE: { CONTROLReleaseEvent msg(event); LOG_DEBUG_STR("Received RELEASED(" << msg.cntlrName << ")"); - if (!stopCalibration(msg.cntlrName)) { // will result in CAL_STOPACK event - CONTROLPreparedEvent answer; // when command was sent. - answer.cntlrName = msg.cntlrName; - answer.result = CT_RESULT_CALSTOP_FAILED; - port.send(answer); + if (!stopCalibration()) { // will result in CAL_STOPACK event + sendControlResult(port,CONTROL_RELEASED, getName(), CT_RESULT_CALSTOP_FAILED); } + // wait for CAL_STOPACK break; } - // -------------------- EVENTS RECEIVED FROM CALSERVER -------------------- + case CONTROL_QUIT: + TRAN(CalibrationControl::quiting_state); + break; - case CAL_STARTACK: { - CALStartackEvent ack(event); - CONTROLPreparedEvent answer; -// answer.cntlrName = ack.name; - answer.cntlrName = getName(); - if (ack.status == SUCCESS || ack.status == ERR_ALREADY_REGISTERED) { - LOG_DEBUG ("Start of calibration was succesful"); - answer.result = CT_RESULT_NO_ERROR; - setObservationState(ack.name, CTState::PREPARED); - } - else { - LOG_ERROR("Start of calibration failed, staying in CLAIMED mode"); - answer.result = CT_RESULT_CALSTART_FAILED; - setObservationState(ack.name, CTState::CLAIMED); - } - itsParentPort->send(answer); - } - break; + // -------------------- EVENTS RECEIVED FROM CALSERVER -------------------- case CAL_STOPACK: { CALStopackEvent ack(event); - CONTROLReleasedEvent answer; -// answer.cntlrName = ack.name; - answer.cntlrName = getName(); if (ack.status == SUCCESS) { LOG_DEBUG ("Calibration successfully stopped"); - setObservationState(ack.name, CTState::RELEASED); - answer.result = CT_RESULT_NO_ERROR; + sendControlResult(*itsParentPort, CONTROL_RELEASED, getName(), + CT_RESULT_NO_ERROR); + setState(CTState::RELEASED); } else { LOG_ERROR("Stop of calibration failed, going to SUSPENDED mode"); - setObservationState(ack.name, CTState::SUSPENDED); - answer.result = CT_RESULT_CALSTOP_FAILED; + sendControlResult(*itsParentPort, CONTROL_RELEASED, getName(), + CT_RESULT_CALSTOP_FAILED); + setState(CTState::SUSPENDED); } - itsParentPort->send(answer); break; } @@ -536,86 +511,86 @@ GCFEvent::TResult CalibrationControl::active_state(GCFEvent& event, GCFPortInter // -// claimResources(name) +// quiting_state(event, port) // -bool CalibrationControl::claimResources(const string& name) +// Quiting: send FINISH, wait for answer max 5 seconds, stop +// +GCFEvent::TResult CalibrationControl::quiting_state(GCFEvent& event, + GCFPortInterface& port) { -#if 0 - // claim the resources: - ResourceAllocator::TRcuSubset rcuSubset; - for (TRCUMap::iterator it = m_rcuMap.begin(); it != m_rcuMap.end(); ++it) { - rcuSubset.set(it->first); - } - uint8 rcuControl = getRcuControlValue(itsBandFilter); - - if(!_getResourceAllocator()->claimSRG(shared_from_this(), - _getPriority(), - rcuSubset, - nyquistZone, - rcuControl)) { - errorCode = LD_RESULT_LOW_PRIORITY; - return (false); + LOG_DEBUG_STR ("quiting:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + case F_EXIT: + break; + + case F_ENTRY: { + // update PVSS + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + itsCalServer->close(); + break; } - _getResourceAllocator()->logSRGallocation(); -#endif - return (true); -} + case F_DISCONNECTED: + port.close(); + // fall through!!! + case F_CLOSED: { + ASSERTSTR (&port == itsCalServer, + "F_DISCONNECTED event from port " << port.getName()); + LOG_DEBUG("Connection with CalServer down, sending FINISH"); + CONTROLFinishEvent request; + request.cntlrName = getName(); + request.result = CT_RESULT_NO_ERROR; + itsParentPort->send(request); + itsTimerPort->setTimer(5.0); // wait max 5 seconds for response + } + break; + case F_TIMER: + LOG_DEBUG("Timeout on reception of FINISHED event, too bad."); + setState(CTState::FINISHED); + stop(); + break; -// -// loadPVSSpropertySets -// -void CalibrationControl::loadPVSSpropertySets() -{ -#if 0 - // load propertysets for the rcus - try { - for(vector<uint16>::iterator it = rcuVector.begin(); - it != rcuVector.end(); ++it) { - char scopeString[300]; - int boardRelNr, apRelNr, rcuRelNr; - getRCURelNumbers((*it),rackRelNr,subRackRelNr,boardRelNr,apRelNr,rcuRelNr); - sprintf(scopeString,SCOPE_PIC_RackN_SubRackN_BoardN_APN_RCUN_LFA,rackRelNr,subRackRelNr,boardRelNr,apRelNr,rcuRelNr); - - boost::shared_ptr<GCFExtPropertySet> propSetPtr(new GCFExtPropertySet(scopeString,TYPE_LCU_PIC_LFA,&m_propertySetAnswer)); - propSetPtr->load(); - propSetPtr->subscribeProp(string(PROPNAME_FUNCTIONALITY)); - propSetPtr->requestValue(string(PROPNAME_FUNCTIONALITY)); - m_rcuMap[(*it)]=propSetPtr; - } + // -------------------- EVENT RECEIVED FROM PARENT CONTROL -------------------- + + case CONTROL_FINISHED: { + CONTROLFinishedEvent msg(event); + LOG_DEBUG_STR("Received FINISHED(" << msg.cntlrName << ")"); + LOG_INFO_STR("Normal shutdown of " << getName()); + setState(CTState::FINISHED); + stop(); + break; } - catch(Exception &e) { - LOG_FATAL(formatString("Error claiming SRG: %s",e.message().c_str())); + + default: + status = _defaultEventHandler(event, port); + break; } -#endif + + return (status); } // -// startCalibration(name) +// startCalibration() // -bool CalibrationControl::startCalibration(const string& name) +bool CalibrationControl::startCalibration() { - // search observation - OIter observation = itsObsMap.find(name); - if (observation == itsObsMap.end()) { - LOG_DEBUG_STR(name << " is unknown, ignoring event"); - return(false); - } - // send CALStartEvent string obsName(formatString("observation[%d]{%d}", getInstanceNr(getName()), getObservationNr(getName()))); CALStartEvent calStartEvent; calStartEvent.name = obsName; - calStartEvent.parent = observation->second.antennaArray; + calStartEvent.parent = itsObsPar.antennaArray; calStartEvent.rcumode().resize(1); -// REO rcumode()(0).setMode((RSP_Protocol::RCUSettings::Control::RCUMode)mode); calStartEvent.rcumode()(0).setMode((RSP_Protocol::RCUSettings::Control::RCUMode) - convertFilterSelection(observation->second.bandSelection)); + convertFilterSelection(itsObsPar.filter)); calStartEvent.nyquist_zone = calStartEvent.rcumode()(0).getNyquistZone(); - calStartEvent.subset = observation->second.RCUset; + calStartEvent.subset = itsObsPar.RCUset; LOG_DEBUG(formatString("Sending CALSTART(%s,%s,%d,%08X)", obsName.c_str(), calStartEvent.parent.c_str(), calStartEvent.nyquist_zone, calStartEvent.rcumode()(0).getRaw())); @@ -626,17 +601,10 @@ bool CalibrationControl::startCalibration(const string& name) // -// stopCalibration(name) +// stopCalibration() // -bool CalibrationControl::stopCalibration(const string& name) +bool CalibrationControl::stopCalibration() { - // search observation - OIter observation = itsObsMap.find(name); - if (observation == itsObsMap.end()) { - LOG_DEBUG_STR(name << " is unknown, ignoring event"); - return(false); - } - // send CALStopEvent string obsName(formatString("observation[%d]{%d}", getInstanceNr(getName()), getObservationNr(getName()))); @@ -645,106 +613,72 @@ bool CalibrationControl::stopCalibration(const string& name) calStopEvent.name = obsName; itsCalServer->send(calStopEvent); -#if 0 - itsResourceAllocator->releaseSRG(shared_from_this()); // TODO - itsResourceAllocator->logSRGallocation(); -#endif - return (true); } +// _defaultEventHandler(event, port) // -// _connectedHandler(port) -// -void CalibrationControl::_connectedHandler(GCFPortInterface& port) +GCFEvent::TResult CalibrationControl::_defaultEventHandler(GCFEvent& event, + GCFPortInterface& port) { -} + CTState cts; + LOG_DEBUG_STR("Received " << evtstr(event) << " in state " << cts.name(itsState) + << ". DEFAULT handling."); -// -// _disconnectedHandler(port) -// -void CalibrationControl::_disconnectedHandler(GCFPortInterface& port) -{ - port.close(); -} + GCFEvent::TResult result(GCFEvent::NOT_HANDLED); + switch (event.signal) { + case CONTROL_CONNECT: + case CONTROL_RESYNC: + case CONTROL_SCHEDULE: // we should do something with this + case CONTROL_CLAIM: + case CONTROL_PREPARE: + case CONTROL_RESUME: + case CONTROL_SUSPEND: + case CONTROL_RELEASE: + case CONTROL_FINISH: + if (sendControlResult(port, event.signal, getName(), CT_RESULT_NO_ERROR)) { + result = GCFEvent::HANDLED; + } + break; -// -// addObservation(name) -// -bool CalibrationControl::addObservation(const string& name) -{ - // Already in admin? return error. - if (itsObsMap.find(name) != itsObsMap.end()) { - LOG_DEBUG_STR(name << " already in admin, returning error"); - return (false); + case CONTROL_CONNECTED: + case CONTROL_RESYNCED: + case CONTROL_SCHEDULED: + case CONTROL_CLAIMED: + case CONTROL_PREPARED: + case CONTROL_RESUMED: + case CONTROL_SUSPENDED: + case CONTROL_RELEASED: + case CONTROL_FINISHED: + result = GCFEvent::HANDLED; + break; } - // find and read parameterset of this observation. - ParameterSet theObsPS; - LOG_TRACE_OBJ_STR("Trying to readfile " << LOFAR_SHARE_LOCATION << "/" << name); - theObsPS.adoptFile(string(LOFAR_SHARE_LOCATION) + "/" + name); - - ObsInfo_t theNewObs; - theNewObs.state = CTState::CREATED; - theNewObs.nyquistZone = theObsPS.getInt16("Observation.nyquistZone"); - theNewObs.sampleFreq = theObsPS.getUint32("Observation.sampleClock"); - theNewObs.bandSelection = theObsPS.getString("Observation.bandFilter"); - theNewObs.antennaArray = theObsPS.getString("Observation.antennaArray"); - vector<uint16> RCUnumbers(theObsPS.getUint16Vector("Observation.receiverList")); - if (RCUnumbers.empty()) { // No receivers in list? - theNewObs.RCUset.set(); // assume all receivers - } - else { - theNewObs.RCUset.reset(); // clear set. - for (uint i = 0; i < RCUnumbers.size(); i++) { - theNewObs.RCUset.set(RCUnumbers[i]); // set mentioned receivers - } + if (result == GCFEvent::NOT_HANDLED) { + LOG_WARN_STR("Event " << evtstr(event) << " NOT handled in state " << + cts.name(itsState)); } - LOG_DEBUG_STR("Adding " << name << " to administration"); - itsObsMap[name] = theNewObs; - - return (true); + return (result); } + // -// handleClaimEvent(observation) +// _connectedHandler(port) // -uint16 CalibrationControl::handleClaimEvent(const string& name) +void CalibrationControl::_connectedHandler(GCFPortInterface& /*port*/) { - // search observation - OIter observation = itsObsMap.find(name); - if (observation == itsObsMap.end()) { - LOG_DEBUG_STR(name << " is unknown, ignoring event"); - return(CT_RESULT_CLAIM_FAILED); - } - - // check if receivers are available - if (!claimResources(name)) { - LOG_ERROR_STR (name << ":failed to claim resources, staying in idle mode"); - return (CT_RESULT_CLAIM_FAILED); - } - - LOG_DEBUG_STR (name << ":resources claimed successful"); - observation->second.state = CTState::CLAIMED; - return (CT_RESULT_NO_ERROR); } // -// setObservationState(name, state) +// _disconnectedHandler(port) // -void CalibrationControl::setObservationState(const string& name, - CTState::CTstateNr newState) +void CalibrationControl::_disconnectedHandler(GCFPortInterface& port) { - // search observation - OIter observation = itsObsMap.find(name); - if (observation == itsObsMap.end()) { - return; - } - - observation->second.state = newState; + port.close(); } + }; // StationCU }; // LOFAR diff --git a/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.h b/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.h index 9f4fd1ef23a4a06ade1b9f3ad6e0bb6852e309cf..93c1d1da1240b2ec32204527c074f169dd370c66 100644 --- a/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.h +++ b/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.h @@ -28,30 +28,26 @@ //# GCF Includes #include <GCF/PAL/GCF_MyPropertySet.h> -#include <GCF/PAL/GCF_ExtPropertySet.h> +//#include <GCF/PAL/GCF_ExtPropertySet.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/APLCommonExceptions.h> +//#include <APL/APLCommon/Controller_Protocol.ph> #include <APL/APLCommon/ParentControl.h> +#include <APL/APLCommon/Observation.h> #include <APL/APLCommon/CTState.h> //# Common Includes #include <Common/lofar_string.h> -#include <Common/lofar_vector.h> -//#include <Common/lofar_bitset.h> -#include <bitset> -#include <Common/LofarLogger.h> +//#include <bitset> //# ACC Includes -#include <APS/ParameterSet.h> +//#include <APS/ParameterSet.h> // forward declaration @@ -80,12 +76,10 @@ public: GCFEvent::TResult initial_state (GCFEvent& e, GCFPortInterface& p); GCFEvent::TResult started_state (GCFEvent& e, GCFPortInterface& p); GCFEvent::TResult claimed_state (GCFEvent& e, GCFPortInterface& p); - - // During the PVSS state the PVSS parametersets are loaded - GCFEvent::TResult PVSS_state (GCFEvent& e, GCFPortInterface& p); - // Normal control mode. GCFEvent::TResult active_state (GCFEvent& e, GCFPortInterface& p); + // Quiting, shutdown connections, send FINISH and quit + GCFEvent::TResult quiting_state (GCFEvent& e, GCFPortInterface& p); private: // avoid defaultconstruction and copying @@ -95,66 +89,32 @@ private: void _connectedHandler(GCFPortInterface& port); void _disconnectedHandler(GCFPortInterface& port); + GCFEvent::TResult _defaultEventHandler(GCFEvent& event, GCFPortInterface& port); void setState (CTState::CTstateNr newState); - void setObservationState (const string& name, CTState::CTstateNr newState); int32 convertFilterSelection(const string& bandselection); - bool propertySetsAvailable (); - int32 getRCUHardwareNr (const string& propName); - void loadPVSSpropertySets (); - bool claimResources (const string& name); - bool addObservation (const string& name); - uint16 handleClaimEvent (const string& name); - uint16 handlePrepareEvent (const string& name); - bool startCalibration (const string& name); - bool stopCalibration (const string& name); + uint16 handleClaimEvent (); + uint16 handlePrepareEvent (); + bool startCalibration (); + bool stopCalibration (); typedef boost::shared_ptr<GCF::PAL::GCFMyPropertySet> GCFMyPropertySetPtr; - typedef std::bitset<256> RCUset_t; APLCommon::PropertySetAnswer itsPropertySetAnswer; GCFMyPropertySetPtr itsPropertySet; bool itsPropertySetInitialized; - // Administration of the Observations we serve. - typedef struct { - uint16 state; // state the observation has - int16 nyquistZone; // 0 | 1 | 2 - uint32 sampleFreq; // 160e6 | 200e6 - string bandSelection; // LB_10_90, HB_110_190, etc - string antennaArray; // CS1_LBA (AntennaArray.conf) - RCUset_t RCUset; // set with participating receivers - } ObsInfo_t; - typedef map<string,ObsInfo_t>::iterator OIter; - typedef map<string,ObsInfo_t>::const_iterator const_OIter; - //# --- Datamembers --- - ParentControl* itsParentControl; // pointer to parent control task GCFITCPort* itsParentPort; // comm.port with parent task GCFTimerPort* itsTimerPort; // general port for timers GCFTCPPort* itsCalServer; // connection with CalServer -// CTState::CTstateNr itsState; // - - map<string /*name*/, ObsInfo_t> itsObsMap; // Map with all active Observations + CTState::CTstateNr itsState; // // ParameterSet variables string itsTreePrefix; uint32 itsInstanceNr; - time_t itsStartTime; - time_t itsStopTime; - uint32 itsPropSetAvailTimer; - -// int16 itsNyquistZone; -// string itsBandSelection; -// string itsAntennaArray; -// vector<uint16> itsRCUvector; - - //TODO - typedef map<uint16,bool> TRCUFunctionalityMap; - TRCUFunctionalityMap m_rcuFunctionalityMap; - typedef map<uint16,boost::shared_ptr<GCF::PAL::GCFExtPropertySet> > TRCUMap; - TRCUMap m_rcuMap; + APLCommon::Observation itsObsPar; }; };//StationCU diff --git a/MAC/APL/StationCU/src/StationControl/ActiveObs.cc b/MAC/APL/StationCU/src/StationControl/ActiveObs.cc index 20b5e73cbaa4c8d3b5f087b764098ae8be3e111c..ea2f8617c56a2fc2831f94a59b55ea1d00a65e3e 100644 --- a/MAC/APL/StationCU/src/StationControl/ActiveObs.cc +++ b/MAC/APL/StationCU/src/StationControl/ActiveObs.cc @@ -346,27 +346,26 @@ GCFEvent::TResult ActiveObs::stopping(GCFEvent& event, GCFPortInterface& /*port* LOG_DEBUG_STR(itsName << ":stopping"); switch (event.signal) { - case F_ENTRY: + case F_ENTRY: { itsBeamCntlrReady = false; itsCalCntlrReady = false; - LOG_DEBUG_STR(itsName << ": in 'stopping-mode' until controllers are down"); - break; - case CONTROL_QUIT: { // release beam at the BeamController LOG_DEBUG_STR("Asking " << itsBeamCntlrName << " to quit"); ChildControl::instance()-> requestState(CTState::FINISHED, itsBeamCntlrName, 0, CNTLRTYPE_NO_TYPE); - // will result in CONTROL_RELEASED + // will result in CONTROL_FINISHED LOG_DEBUG_STR("Asking " << itsCalCntlrName << " to quit"); ChildControl::instance()-> requestState(CTState::FINISHED, itsCalCntlrName, 0, CNTLRTYPE_NO_TYPE); - // will result in CONTROL_RELEASED + // will result in CONTROL_FINISHED + + LOG_DEBUG_STR(itsName << ": in 'stopping-mode' until controllers are down"); } break; - case CONTROL_FINISHED: { + case CONTROL_FINISH: { CONTROLFinishedEvent msg(event); if (msg.cntlrName == itsCalCntlrName) { itsCalCntlrReady = true; diff --git a/MAC/APL/StationCU/src/StationControl/StationControl.cc b/MAC/APL/StationCU/src/StationControl/StationControl.cc index 5f4081de1ee6e422c91bb570b0f3cdcf549b43e8..358bedfbb4c76cac7d1b012b3f507aef83510d50 100644 --- a/MAC/APL/StationCU/src/StationControl/StationControl.cc +++ b/MAC/APL/StationCU/src/StationControl/StationControl.cc @@ -278,7 +278,7 @@ GCFEvent::TResult StationControl::connect_state(GCFEvent& event, 0, // treeID, 0, // instanceNr, myHostname(true)); - // will result in CONTROL_STARTED and CONTROL_CONNECT if not error. + // will result in CONTROL_STARTED (and CONTROL_CONNECTED if no error). } break; @@ -370,9 +370,10 @@ GCFEvent::TResult StationControl::operational_state(GCFEvent& event, GCFPortInte CONTROLConnectedEvent answer; answer.cntlrName = msg.cntlrName; // add observation to the list if not already in the list - answer.result = _addObservation(msg.cntlrName) ? - CT_RESULT_NO_ERROR : CT_RESULT_UNSPECIFIED; - port.send(answer); + answer.result = _addObservation(msg.cntlrName); + if (answer.result != CT_RESULT_NO_ERROR) { + port.send(answer); + } } break; @@ -389,6 +390,7 @@ GCFEvent::TResult StationControl::operational_state(GCFEvent& event, GCFPortInte case CONTROL_RESUME: case CONTROL_SUSPEND: case CONTROL_RELEASE: + case CONTROL_FINISH: case CONTROL_QUIT: { // All the events have the problem that the controller can be StationControl, // CalibrationControl or BeamControl. But what they all have in common is @@ -418,18 +420,29 @@ GCFEvent::TResult StationControl::operational_state(GCFEvent& event, GCFPortInte theObs->second->dispatch(event, port); // end of FSM? - if (event.signal == CONTROL_QUIT && theObs->second->isReady()) { + if (event.signal == CONTROL_FINISH && theObs->second->isReady()) { LOG_DEBUG_STR("Removing " <<ObsEvent.cntlrName<< " from the administration"); delete theObs->second; itsObsMap.erase(theObs); - break; } // check if all actions for this event are finished. +LOG_TRACE_FLOW("Counting busy controllers..."); vector<ChildControl::StateInfo> cntlrStates = itsChildControl->getPendingRequest("", treeID); +LOG_TRACE_FLOW_STR("There are " << cntlrStates.size() << " busy controllers"); if (cntlrStates.empty()) { // no pending requests? Ready. - sendControlResult(*itsParentPort, event.signal, cntlrName, CT_RESULT_NO_ERROR); + if (event.signal != CONTROL_FINISH) { + sendControlResult(*itsParentPort, event.signal, cntlrName, + CT_RESULT_NO_ERROR); + } + else { + // we are done, pass finish request to parent + CONTROLFinishEvent request; + request.cntlrName = cntlrName; + request.result = CT_RESULT_NO_ERROR; + itsParentPort->send(request); + } break; } // Show where we are waiting for. When error occured, report it back and stop @@ -458,12 +471,12 @@ GCFEvent::TResult StationControl::operational_state(GCFEvent& event, GCFPortInte // // addObservation(name) // -bool StationControl::_addObservation(const string& name) +uint16 StationControl::_addObservation(const string& name) { // Already in admin? Return error. if (itsObsMap.find(name) != itsObsMap.end()) { - LOG_DEBUG_STR(name << " already in admin, returning error"); - return (false); + LOG_WARN_STR(name << " already in admin, returning error"); + return (CT_RESULT_ALREADY_REGISTERED); } // find and read parameterset of this observation @@ -474,7 +487,7 @@ bool StationControl::_addObservation(const string& name) ActiveObs* theNewObs = new ActiveObs(name, (State)&ActiveObs::initial, &theObsPS); if (!theNewObs) { LOG_FATAL_STR("Unable to create the Observation '" << name << "'"); - return (false); + return (CT_RESULT_UNSPECIFIED); } LOG_DEBUG_STR("Adding " << name << " to administration"); @@ -482,7 +495,7 @@ bool StationControl::_addObservation(const string& name) LOG_DEBUG_STR(*theNewObs); theNewObs->start(); // call initial state. - return (true); + return (CT_RESULT_NO_ERROR); } diff --git a/MAC/APL/StationCU/src/StationControl/StationControl.h b/MAC/APL/StationCU/src/StationControl/StationControl.h index f1c64a4bca92c7b3038b59fedb60d790bbbb1383..b18df166b6be1b25a27e9671378c198d3b1d12f7 100644 --- a/MAC/APL/StationCU/src/StationControl/StationControl.h +++ b/MAC/APL/StationCU/src/StationControl/StationControl.h @@ -89,8 +89,8 @@ private: StationControl(const StationControl&); StationControl& operator=(const StationControl&); - bool _addObservation(const string& name); - void _disconnectedHandler(GCFPortInterface& port); + uint16 _addObservation(const string& name); + void _disconnectedHandler(GCFPortInterface& port); // Data members APLCommon::PropertySetAnswer itsPropertySetAnswer;