From 6b754a749d24be908c3cf801fac7c8ff3139fc57 Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Thu, 15 Jun 2006 10:14:23 +0000
Subject: [PATCH] BugID: 679 Moved Observation control to its right place. (was
 developped in MACScheduler directory for convenience).

---
 .../APLObservationControl.dpl                 |  18 +
 .../MainCU/src/ObservationControl/Makefile.am |  44 +++
 .../ObservationControl/ObservationControl.cc  | 369 ++++++++++++++++++
 .../ObservationControl.conf.in                |  11 +
 .../ObservationControl/ObservationControl.h   | 133 +++++++
 .../ObservationControl.log_prop.in            |  20 +
 .../ObservationControlDefines.h               |  43 ++
 .../ObservationControlMain.cc                 |  49 +++
 8 files changed, 687 insertions(+)
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/APLObservationControl.dpl
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/Makefile.am
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControlMain.cc

diff --git a/MAC/APL/MainCU/src/ObservationControl/APLObservationControl.dpl b/MAC/APL/MainCU/src/ObservationControl/APLObservationControl.dpl
new file mode 100644
index 00000000000..a5c5d6ad628
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/APLObservationControl.dpl
@@ -0,0 +1,18 @@
+# ascii dump of database
+
+# DpType
+#TypeName
+#LOFAR.LOFAR	1#1
+#	state	25#2
+
+TypeName
+ObsSW.ObsSW	1#1
+	state	25#2
+
+TypeName
+ObsCtrl.ObsCtrl	1#1
+	state	25#2
+	error	25#3
+	observationState	25#4
+	
+	
diff --git a/MAC/APL/MainCU/src/ObservationControl/Makefile.am b/MAC/APL/MainCU/src/ObservationControl/Makefile.am
new file mode 100644
index 00000000000..20ba1eca523
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/Makefile.am
@@ -0,0 +1,44 @@
+bin_PROGRAMS 				= ObservationControl
+
+ObservationControl_CPPFLAGS		= -Wno-deprecated \
+								  -fmessage-length=0 \
+								  -fdiagnostics-show-location=once
+
+ObservationControl_SOURCES		= ObservationControl.cc \
+								  ObservationControlMain.cc 
+
+ObservationControl_LDADD		= $(LOFAR_DEPEND)
+ObservationControl_DEPENDENCIES	= $(LOFAR_DEPEND)
+
+NOINSTHDRS 					= ObservationControl.h \
+							  ObservationControlDefines.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 	= 
+#customPrepPVSSDB.ctl
+
+sysconf_DATA		= ObservationControl.conf \
+					  ObservationControl.log_prop
+
+%.log_prop: %.log_prop.in
+	cp $< $@
+
+%.conf: %.conf.in
+	cp $< $@
+
+%.ctl: %.ctl.in
+	cp $< $@
+
+clean-local:
+	rm -f *.ph
+
+include $(top_srcdir)/Makefile.common
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
new file mode 100644
index 00000000000..128311c1ac4
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
@@ -0,0 +1,369 @@
+//#  ObservationControl.cc: Implementation of the MAC Scheduler 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 <Common/LofarLogger.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/GCF_ServiceInfo.h>
+#include <GCF/Protocols/PA_Protocol.ph>
+#include <APL/APLCommon/APL_Defines.h>
+#include <APL/APLCommon/APLCommonExceptions.h>
+#include <APL/APLCommon/Controller_Protocol.ph>
+
+#include "ObservationControl.h"
+#include "ObservationControlDefines.h"
+
+using namespace LOFAR::GCF::Common;
+using namespace LOFAR::GCF::TM;
+using namespace LOFAR::GCF::PAL;
+using namespace LOFAR::OTDB;
+using namespace std;
+
+namespace LOFAR {
+	using namespace APLCommon;
+	using namespace ACC::APS;
+	namespace MainCU {
+	
+//
+// ObservationControl()
+//
+ObservationControl::ObservationControl(const string&	cntlrName) :
+	GCFTask 			((State)&ObservationControl::initial_state,cntlrName),
+	PropertySetAnswerHandlerInterface(),
+	itsPropertySetAnswer(*this),
+	itsPropertySet		(),
+	itsChildControl		(0),
+	itsChildPort		(0),
+	itsParentControl	(0),
+	itsParentPort		(0),
+	itsTimerPort		(0)
+{
+	LOG_TRACE_OBJ_STR (cntlrName << " construction");
+
+	// 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");
+
+	// attach to child control task
+	itsChildControl = ChildControl::instance();
+	itsChildPort = new GCFITCPort (*this, *itsChildControl, "childITCport", 
+									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol");
+	itsChildPort->open();		// will result in F_CONNECTED
+
+	// attach to parent control task
+	itsParentControl = ParentControl::instance();
+	itsParentPort = new GCFITCPort (*this, *itsParentControl, "ParentITCport", 
+									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsChildPort, "Cannot allocate ITCport for Parentcontrol");
+	itsParentPort->open();		// will result in F_CONNECTED
+
+	// need port for timers.
+	itsTimerPort = new GCFTimerPort(*this, "TimerPort");
+
+	registerProtocol (CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_signalnames);
+	registerProtocol (PA_PROTOCOL, 		   PA_PROTOCOL_signalnames);
+}
+
+
+//
+// ~ObservationControl()
+//
+ObservationControl::~ObservationControl()
+{
+	LOG_TRACE_OBJ_STR (getName() << " destruction");
+
+	if (itsPropertySet) {
+		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("down"));
+		itsPropertySet->disable();
+	}
+
+	// ...
+}
+
+
+//
+// handlePropertySetAnswer(answer)
+//
+void ObservationControl::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(0.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.
+		// change of queueTime
+		if ((strstr(pPropAnswer->pPropName, OC_PROPSET_NAME) != 0) &&
+			(pPropAnswer->pValue->getType() == LPT_INTEGER)) {
+			uint32	newVal = (uint32) ((GCFPVInteger*)pPropAnswer->pValue)->getValue();
+#if 0
+			if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_QUEUEPERIOD) != 0) {
+				LOG_INFO_STR ("Changing QueuePeriod from " << itsQueuePeriod <<
+							  " to " << newVal);
+				itsQueuePeriod = newVal;
+			}
+			else if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_CLAIMPERIOD) != 0) {
+				LOG_INFO_STR ("Changing ClaimPeriod from " << itsClaimPeriod <<
+							  " to " << newVal);
+				itsClaimPeriod = newVal;
+			}
+#endif
+		}
+		break;
+	}  
+
+	default:
+		break;
+	}  
+}
+
+
+//
+// initial_state(event, port)
+//
+// Setup all connections.
+//
+GCFEvent::TResult ObservationControl::initial_state(GCFEvent& event, 
+													GCFPortInterface& port)
+{
+	LOG_DEBUG_STR ("initial:" << evtstr(event) << "@" << port.getName());
+
+	GCFEvent::TResult status = GCFEvent::HANDLED;
+  
+	switch (event.signal) {
+    case F_INIT:
+   		break;
+
+	case F_ENTRY: {
+		// Get access to my own propertyset.
+		LOG_DEBUG ("Activating PropertySet");
+		string	propSetName = formatString(OC_PROPSET_NAME, itsInstanceNr);
+		itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(),
+																  OC_PROPSET_TYPE,
+																  PS_CAT_TEMPORARY,
+																  &itsPropertySetAnswer));
+		itsPropertySet->enable();
+		// Wait for timer that is set in PropertySetAnswer on ENABLED event
+		}
+		break;
+	  
+	case F_TIMER: {		// must be timer that PropSet has set.
+		// 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 ChildControl task
+		LOG_DEBUG ("Enabling ChildControl task");
+		itsChildControl->openService(MAC_SVCMASK_OBSERVATIONCTRL, itsInstanceNr);
+		itsChildControl->registerCompletionPort(itsChildPort);
+
+		// Start ParentControl task
+		LOG_DEBUG ("Enabling ParentControl task");
+		itsParentPort = itsParentControl->registerTask(this);
+
+		TRAN(ObservationControl::active_state);				// go to next state.
+		}
+		break;
+
+	case F_CONNECTED:
+		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 ObservationControl::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:
+		break;
+
+	case F_ENTRY: {
+		// update PVSS
+		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active"));
+		itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString(""));
+		break;
+	}
+
+	case F_ACCEPT_REQ:
+		break;
+
+	case F_CONNECTED:	
+		_connectedHandler(port);
+		break;
+
+	case F_DISCONNECTED:	
+		_disconnectedHandler(port);
+		break;
+
+	case F_TIMER: 
+//		GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event);
+		break;
+
+	// -------------------- EVENT RECEIVED FROM CHILD CONTROL --------------------
+	case CONTROL_STARTED: {
+		CONTROLStartedEvent	msg(event);
+		LOG_DEBUG(formatString("Start of %s was %ssuccessful", msg.cntlrName.c_str(), 
+						msg.successful ? "" : "NOT "));
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_CONNECT: {
+		CONTROLConnectEvent		msg(event);
+		LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_SCHEDULED: {
+		CONTROLScheduledEvent		msg(event);
+		LOG_DEBUG_STR("Received SCHEDULED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_CLAIMED: {
+		CONTROLClaimedEvent		msg(event);
+		LOG_DEBUG_STR("Received CLAIMED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_PREPARED: {
+		CONTROLPreparedEvent		msg(event);
+		LOG_DEBUG_STR("Received PREPARED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_RESUMED: {
+		CONTROLResumedEvent		msg(event);
+		LOG_DEBUG_STR("Received RESUMED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_SUSPENDED: {
+		CONTROLSuspendedEvent		msg(event);
+		LOG_DEBUG_STR("Received SUSPENDED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_RELEASED: {
+		CONTROLReleasedEvent		msg(event);
+		LOG_DEBUG_STR("Received RELEASED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_FINISH: {
+		CONTROLFinishEvent		msg(event);
+		LOG_DEBUG_STR("Received FINISH(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+
+	default:
+		LOG_DEBUG("active_state, default");
+		status = GCFEvent::NOT_HANDLED;
+		break;
+	}
+
+	return (status);
+}
+
+
+//
+// _connectedHandler(port)
+//
+void ObservationControl::_connectedHandler(GCFPortInterface& port)
+{
+}
+
+//
+// _disconnectedHandler(port)
+//
+void ObservationControl::_disconnectedHandler(GCFPortInterface& port)
+{
+	port.close();
+}
+
+
+};
+};
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
new file mode 100644
index 00000000000..a92957c18ce
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
@@ -0,0 +1,11 @@
+# new setup
+prefix	=	Observation0
+
+Observation0.instanceNr = 0
+Observation0.starttime	= 0
+Observation0.stoptime	= 1
+
+# next parameters are optional, defaultvalues are shown
+#ChildControl.StartupRetryInterval = 10s
+#ChildControl.MaxStartupRetry	   = 5
+
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
new file mode 100644
index 00000000000..6077c0f8ce0
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
@@ -0,0 +1,133 @@
+//#  ObservationControl.h: Interface between MAC and SAS.
+//#
+//#  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$
+
+#ifndef ObservationControl_H
+#define ObservationControl_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/ChildControl.h>
+#include <APL/APLCommon/ParentControl.h>
+#include <APL/APLCommon/CTState.h>
+
+//# Common Includes
+#include <Common/lofar_string.h>
+#include <Common/lofar_vector.h>
+#include <Common/LofarLogger.h>
+
+//# ACC Includes
+#include <APS/ParameterSet.h>
+
+// forward declaration
+
+namespace LOFAR {
+	namespace MainCU {
+
+using	GCF::TM::GCFTimerPort;
+using	GCF::TM::GCFITCPort;
+using	GCF::TM::GCFPort;
+using	GCF::TM::GCFEvent;
+using	GCF::TM::GCFPortInterface;
+using	GCF::TM::GCFTask;
+
+
+class ObservationControl : public GCFTask,
+						   APLCommon::PropertySetAnswerHandlerInterface
+{
+public:
+	explicit ObservationControl(const string& cntlrName);
+	~ObservationControl();
+
+   	// PropertySetAnswerHandlerInterface method
+   	virtual 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);
+
+private:
+	// avoid defaultconstruction and copying
+	ObservationControl();
+	ObservationControl(const ObservationControl&);
+   	ObservationControl& operator=(const ObservationControl&);
+
+   	void _connectedHandler(GCFPortInterface& port);
+   	void _disconnectedHandler(GCFPortInterface& port);
+   	boost::shared_ptr<ACC::APS::ParameterSet> 
+		 readObservationParameters (OTDB::treeIDType	ObsTreeID);
+
+   	typedef boost::shared_ptr<GCF::PAL::GCFMyPropertySet> GCFMyPropertySetPtr;
+
+   	APLCommon::PropertySetAnswer  itsPropertySetAnswer;
+   	GCFMyPropertySetPtr           itsPropertySet;
+
+#if 0
+	// Administration of the ObservationControllers
+	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 ObservationControllers.
+	map<GCFTCPPort*, ObsCntlr_t>	itsObsCntlrMap;
+	vector<GCFTCPPort*>				itsObsCntlrPorts;
+#endif
+
+	// pointer to child control task
+	ChildControl*			itsChildControl;
+	GCFITCPort*				itsChildPort;
+
+	// pointer to parent control task
+	ParentControl*			itsParentControl;
+	GCFITCPort*				itsParentPort;
+
+	GCFTimerPort*			itsTimerPort;
+
+	// ParameterSet variables
+	string					itsTreePrefix;
+	uint32					itsInstanceNr;
+	time_t					itsStartTime;
+	time_t					itsStopTime;
+};
+
+  };//MainCU
+};//LOFAR
+#endif
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in
new file mode 100644
index 00000000000..014e32162d9
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.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=%x %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/ObservationControl.log
+log4cplus.appender.FILE.MaxFileSize=5MB
+log4cplus.appender.FILE.MaxBackupIndex=5
+log4cplus.appender.FILE.layout=log4cplus::PatternLayout
+log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%.25l]%n
+
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h b/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h
new file mode 100644
index 00000000000..1944eb625d3
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h
@@ -0,0 +1,43 @@
+//#  MACScheduler_Defines.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 OBSERVATIONDEFINES_H
+#define OBSERVATIONDEFINES_H
+
+namespace LOFAR {
+  namespace MCU {
+
+#define OC_TASKNAME					"ObsCtrl"
+
+#define OC_PROPSET_NAME				"LOFAR_ObsSW_ObsCtrl%d"
+#define OC_PROPSET_TYPE				"ObsCtrl"
+#define OC_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/MainCU/src/ObservationControl/ObservationControlMain.cc b/MAC/APL/MainCU/src/ObservationControl/ObservationControlMain.cc
new file mode 100644
index 00000000000..08586805586
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControlMain.cc
@@ -0,0 +1,49 @@
+//#  ObservationControlMain.cc: Main entry for the ObservationControl 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 "ObservationControl.h"
+
+using namespace LOFAR::GCF::TM;
+using namespace LOFAR::MainCU;
+
+int main(int argc, char* argv[])
+{
+	// args: cntlrname, parentHost, parentService
+	GCFTask::init(argc, argv);
+
+	ChildControl*	cc = ChildControl::instance();
+	cc->start();	// make initial transition
+
+	ParentControl*	pc = ParentControl::instance();
+	pc->start();	// make initial transition
+
+	ObservationControl	oc(argv[1]);
+	oc.start(); // make initial transition
+
+	GCFTask::run();
+
+	return 0;
+}
+
-- 
GitLab