diff --git a/.gitattributes b/.gitattributes index 3995dc17155abbb58bacf03482327fe92d8bfa82..89f357755c701dbdd4f662ea05161d924e856a9e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -283,8 +283,6 @@ MAC/APL/_VIC/VirtualInstrument/bootstrap -text svneol=native#application/octet-s MAC/APL/_VIC/VirtualInstrument/configure.in -text svneol=native#application/octet-stream MAC/APL/_VIC/VirtualInstrument/src/APLVI.dpl -text svneol=native#application/octet-stream MAC/APL/_VIC/VirtualInstrument/src/Makefile.am -text svneol=native#application/octet-stream -MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.in -text svneol=native#application/octet-stream -MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.log_prop.in -text svneol=native#application/octet-stream MAC/APL/_VIC/VirtualInstrument/test/MAINTENANCE1.param -text svneol=native#application/octet-stream MAC/APL/_VIC/VirtualInstrument/test/Makefile.am -text svneol=native#application/octet-stream MAC/APL/_VIC/VirtualInstrument/test/SO.param -text svneol=native#application/octet-stream @@ -335,7 +333,6 @@ MAC/GCF/TM/configure.in -text svneol=native#application/octet-stream MAC/GCF/TM/src/Makefile.am -text svneol=native#application/octet-stream MAC/GCF/TM/src/ServiceBroker/Makefile.am -text svneol=native#application/octet-stream MAC/GCF/TM/src/ServiceBroker/SB_Protocol.prot -text svneol=native#application/octet-stream -MAC/GCF/TM/src/ServiceBroker/gcf-sb.conf.in -text svneol=native#application/octet-stream MAC/GCF/TM/test/Echo_Protocol.prot -text svneol=native#application/octet-stream MAC/GCF/TM/test/Makefile.am -text svneol=native#application/octet-stream MAC/GCF/TM/test/tm-test.conf.in -text svneol=native#application/octet-stream diff --git a/MAC/APL/CUDaemons/configure.in b/MAC/APL/CUDaemons/configure.in index 83d6dcf65c8b977b57ef35b1d69922fb0b4b172a..23f53b21a26a27ef4aff3707262444ca7585591b 100644 --- a/MAC/APL/CUDaemons/configure.in +++ b/MAC/APL/CUDaemons/configure.in @@ -56,21 +56,17 @@ lofar_GENERAL lofar_COMPILETOOLS lofar_PVSS(1) lofar_INTERNAL(LCS/Common, common, LCS-Common-2_3, 1, Common/LofarTypes.h,,) -lofar_INTERNAL(LCS/ACC/APS, aps, LCS-ACC-2_0, 1, APS/ParameterSet.h,,) -dnl lofar_INTERNAL(SAS/OTDB, otdb, HEAD, 1, OTDB/OTDBconnection.h,,) -lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, MAC-GCF-6_0, 1, GCF/GCF_Defines.h,,) -lofar_INTERNAL(MAC/GCF/TM, gcftm, MAC-GCF-6_0, 1, GCF/TM/GCF_Task.h,,) -dnl lofar_INTERNAL(MAC/GCF/PAL, gcfpal, MAC-GCF-6_0, 1, GCF/PAL/GCF_PVSSInfo.h,,) -lofar_INTERNAL(MAC/APL/APLCommon, aplcommon, MAC-APL-3_1, 1, APL/APLCommon/APL_Defines.h,,) -dnl lofar_EXTERNAL(boost,1.32,boost/date_time/date.hpp, boost_date_time-gcc) -dnl lofar_EXTERNAL(pqxx,2.5.5,pqxx/pqxx, pqxx) -dnl lofar_EXTERNAL(pq,,libpq-fe.h, pq, /usr/local/pgsql) +lofar_INTERNAL(LCS/ACC/APS, aps, , 1, APS/ParameterSet.h,,) +lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, , 1, GCF/GCF_Defines.h,,) +lofar_INTERNAL(MAC/GCF/TM, gcftm, , 1, GCF/TM/GCF_Task.h,,) +lofar_INTERNAL(MAC/APL/APLCommon, aplcommon, , 1, APL/APLCommon/APL_Defines.h,,) dnl dnl Output Makefiles dnl AC_OUTPUT( src/Makefile +test/Makefile src/LDStartDaemon/Makefile Makefile CUDaemons.spec diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.cc b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.cc index 672dc69ac5f61c0c59ddc861004fdf4882e118da..e3fa9b2aa8e985b3b16154d4ad8f92f166e51a27 100644 --- a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.cc +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.cc @@ -1,4 +1,4 @@ -//# StartDaemon.cc: Base class for logical device factories. +//# LDStartDaemon.cc: Program that can start others on command. //# //# Copyright (C) 2002-2004 //# ASTRON (Netherlands Foundation for Research in Astronomy) @@ -19,282 +19,108 @@ //# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //# //# $Id$ -#undef PACKAGE -#undef VERSION #include <lofar_config.h> #include <Common/LofarLogger.h> -#include <GCF/GCF_PVInteger.h> -#include <GCF/PAL/GCF_PVSSInfo.h> +#include <GCF/GCF_ServiceInfo.h> #include <APL/APLCommon/APL_Defines.h> #include <APL/APLCommon/APLUtilities.h> -#include "APL/APLCommon/LogicalDevice.h" - -#ifdef CREATING_TASKS -#include "APL/STSCtl/LogicalDeviceFactoryBase.h" -#else -#include "APL/STSCtl/LDstarter.h" -#endif -#include "APL/STSCtl/StartDaemon.h" -#include "StartDaemon_Protocol.ph" +#include <APL/APLCommon/StartDaemon_Protocol.ph> +#include "LogicalDeviceStarter.h" +#include "LDStartDaemon.h" using namespace LOFAR::GCF::Common; using namespace LOFAR::GCF::TM; -using namespace LOFAR::GCF::PAL; +using namespace LOFAR::ACC::APS; namespace LOFAR { - namespace STSCtl { - -const string StartDaemon::PSTYPE_STARTDAEMON("TAplStartDaemon"); -const string StartDaemon::SD_PROPNAME_COMMAND("command"); -const string StartDaemon::SD_PROPNAME_STATUS("status"); -const string StartDaemon::SD_COMMAND_SCHEDULE("SCHEDULE"); -const string StartDaemon::SD_COMMAND_DESTROY_LD("DESTROY_LOGICALDEVICE"); -const string StartDaemon::SD_COMMAND_STOP("STOP"); - -INIT_TRACER_CONTEXT(StartDaemon,LOFARLOGGER_PACKAGE); + namespace CUDaemons { // -// StartDaemon(systemname(?)) +// LDStartDaemon(taskname) // -// The pvss System Name is necessary to distinguish between startdaemon servers on different systems -StartDaemon::StartDaemon(const string& name) : - GCFTask((State)&StartDaemon::initial_state,name), - PropertySetAnswerHandlerInterface(), - m_propertySetAnswer(*this), - m_properties(name.c_str(),PSTYPE_STARTDAEMON.c_str(),PS_CAT_TEMPORARY,&m_propertySetAnswer), - m_serverPortName(string("server")), - m_serverPort(), - m_childPorts(), - m_factories(), - m_logicalDevices(), - m_garbageCollection(), - m_garbageCollectionTimerId(0) +LDStartDaemon::LDStartDaemon(const string& name) : + GCFTask ((State)&LDStartDaemon::initial_state, name), + itsListener (0), + itsListenRetryTimer (0), + itsClients (), + itsStarter (0) { -#ifndef USE_PVSSPORT - LOG_WARN("Using GCFTCPPort in stead of GCFPVSSPort"); -#endif - - // PVSS must have been initialized before the local system name can - // be retrieved - string taskName = GCFPVSSInfo::getLocalSystemName()+string("_")+name; - setName(taskName); - - // it is important to init the m_serverPort AFTER setting the name - // of the task. - m_serverPort.init(*this, m_serverPortName, GCFPortInterface::MSPP, STARTDAEMON_PROTOCOL), - - registerProtocol(STARTDAEMON_PROTOCOL, STARTDAEMON_PROTOCOL_signalnames); - LOG_DEBUG(formatString("StartDaemon(%s)::StartDaemon",getName().c_str())); - - m_properties.enable(); -} + LOG_TRACE_FLOW(formatString("LDStartDaemon(%s)", getName().c_str())); + itsListener = new GCFTCPPort(*this, MAC_SVCMASK_STARTDAEMON, + GCFPortInterface::MSPP, STARTDAEMON_PROTOCOL); + ASSERTSTR(itsListener, "Unable to allocate listener port"); -// -// ~StartDaemon -// -StartDaemon::~StartDaemon() -{ - LOG_DEBUG(formatString("StartDaemon(%s)::~StartDaemon",getName().c_str())); - m_properties.disable(); -} - -#ifdef CREATING_TASKS -// -// registerFactory(ldType, shared_ptr<LDdactoryBase>) -// -void StartDaemon::registerFactory(TLogicalDeviceTypes ldType, - boost::shared_ptr<LogicalDeviceFactoryBase> factory) -{ - m_factories[ldType] = factory; -} -#else -// -// registerFactory(ldType, shared_ptr<LDstarter>) -// -void StartDaemon::registerFactory(TLogicalDeviceTypes ldType, - boost::shared_ptr<LDstarter> factory) -{ - m_factories[ldType] = factory; -} -#endif - -// -// createLogicalDevice(ldType, taskName, fileName) -// -TSDResult StartDaemon::createLogicalDevice(const TLogicalDeviceTypes ldType, - const string& taskName, - const string& fileName) -{ - // Search ldType in factory - TFactoryMap::iterator itFactories = m_factories.find(ldType); - if(itFactories == m_factories.end()) { - LOG_FATAL_STR("Requested Logical Device (" << ldType << - ") cannot be created by this StartDaemon"); - return (SD_RESULT_UNSUPPORTED_LD); - } - - // Does logical device already exist? - TLogicalDeviceMap::iterator itDevices = m_logicalDevices.find(taskName); - if(itDevices == m_logicalDevices.end()) { - // LD does not exist, try to create it. - try { -#ifdef CREATING_TASKS - boost::shared_ptr<LogicalDevice> ld = - itFactories->second->createLogicalDevice(taskName,fileName,this); - m_logicalDevices[taskName] = ld; - ld->start(); // make initial transition -#else - m_logicalDevices[taskName] = itFactories->second->createLogicalDevice(taskName,fileName); - LOG_DEBUG_STR(toString(getpid()) << ":cid of Logical Device = " << m_logicalDevices[taskName]); -#endif - return (SD_RESULT_NO_ERROR); - } - catch(APLCommon::ParameterFileNotFoundException& e) { - LOG_FATAL(e.message()); - return (SD_RESULT_FILENOTFOUND); - } - catch(APLCommon::ParameterNotFoundException& e) { - LOG_FATAL(e.message()); - return (SD_RESULT_PARAMETERNOTFOUND); - } - catch(APLCommon::WrongVersionException& e) { - LOG_FATAL(e.message()); - return (SD_RESULT_WRONG_VERSION); - } - catch(Exception& e) { - LOG_FATAL(e.message()); - return (SD_RESULT_UNSPECIFIED_ERROR); - } - } - -#ifdef CREATINGS_TASKS - // LD already exists. - if (itFactories->second->sharingAllowed()) { - LOG_INFO(formatString("LogicalDevice %s allows sharing. Updating parameters.",taskName.c_str())); - itFactories->second->createLogicalDevice(taskName,fileName,this); - // ignoring the returned pointer because the instance is already in the logicalDeviceMap - return (SD_RESULT_NO_ERROR); - } - - LOG_FATAL_STR("Requested Logical Device (" << taskName << - ") already exists and sharing is not allowed"); - return (SD_RESULT_ALREADY_EXISTS); -#else - // [TODO] implement identical test (???) - return (SD_RESULT_NO_ERROR); -#endif -} - -// -// destroyLogicalDevice(name) -// -TSDResult StartDaemon::destroyLogicalDevice(const string& name) -{ - // Try to find the device in our map - TLogicalDeviceMap::iterator it = m_logicalDevices.find(name); - if(it == m_logicalDevices.end()) { - return (SD_RESULT_LD_NOT_FOUND); // not found, return error. - } - -#ifdef CREATING_TASKS - // check state of device to destroy - if (it->second->getLogicalDeviceState() != - LogicalDevice::LOGICALDEVICE_STATE_GOINGDOWN) { - return (SD_RESULT_WRONG_STATE); - } -#else - // [TODO] implement identical test(???) -#endif - - LOG_DEBUG(formatString("Adding '%s' to the collection of garbage",name.c_str())); - // add the LD to the collection of garbage. - m_garbageCollection[it->first] = it->second; - m_garbageCollectionTimerId = m_serverPort.setTimer(0L,1000L); // 1000 us - -#ifndef CREATING_TASKS - // [TODO] DO THE REAL KILL -#endif + itsStarter = new LogicalDeviceStarter(globalParameterSet()); + ASSERTSTR(itsStarter, "Unable to allocate starter object"); - // erase the LD from the collection of LD's. - m_logicalDevices.erase(it); - - return (SD_RESULT_NO_ERROR); + registerProtocol(STARTDAEMON_PROTOCOL, STARTDAEMON_PROTOCOL_signalnames); } -// -// _isChildPort(GCFport) -// -bool StartDaemon::_isChildPort(GCFPortInterface& port) -{ - bool found=false; - - TPortVector::iterator it=m_childPorts.begin(); - while(!found && it != m_childPorts.end()) { - found = (&port == (*it).get()); // comparing two pointers. yuck? - ++it; - } - return (found); -} - -// -// _disconnectedHandler(GCFport) // -// Handle a disconnected event on one of the ports +// ~LDStartDaemon // -void StartDaemon::_disconnectedHandler(GCFPortInterface& port) +LDStartDaemon::~LDStartDaemon() { - port.close(); - if(_isServerPort(port)) { - return; - } + LOG_TRACE_FLOW(formatString("~LDStartDaemon(%s)", getName().c_str())); - if(!_isChildPort(port)) { - return; + if (itsListener) { + itsListener->close(); + delete itsListener; } - bool found=false; - TPortVector::iterator it=m_childPorts.begin(); - while(!found && it != m_childPorts.end()) { - found = (&port == (*it).get()); // comparing two pointers. yuck? - if(found) { - m_childPorts.erase(it); - } - else { - ++it; - } + if (itsStarter) { + delete itsStarter; } } // // initial_state(event, port) // -GCFEvent::TResult StartDaemon::initial_state(GCFEvent& event, GCFPortInterface& port) +// The only target in this state is to get the listener port on the air. +// +GCFEvent::TResult LDStartDaemon::initial_state(GCFEvent& event, + GCFPortInterface& /*port*/) { - LOG_DEBUG(formatString("StartDaemon(%s)::initial_state (%s)",getName().c_str(),evtstr(event))); + LOG_DEBUG(formatString("LDStartDaemon(%s)::initial_state (%s)",getName().c_str(),evtstr(event))); GCFEvent::TResult status = GCFEvent::HANDLED; switch (event.signal) { - case F_INIT: + case F_INIT: break; - case F_ENTRY: { - TRAN(StartDaemon::idle_state); - break; + case F_ENTRY: { + itsListener->open(); // may result in CONN or DISCONN event + break; + } + + case F_CONNECTED: // Must be from itsListener port + if (itsListener->isConnected()) { + if (itsListenRetryTimer) { + itsListener->cancelTimer(itsListenRetryTimer); + itsListenRetryTimer = 0; + } + LOG_DEBUG ("Listener port opened, going to operational mode"); + TRAN(LDStartDaemon::operational_state); } - - case F_CONNECTED: break; - case F_DISCONNECTED: - port.close(); + case F_DISCONNECTED: // Must be from itsListener port + LOG_DEBUG("Could not open listener, retry in 1 second"); + itsListenRetryTimer = itsListener->setTimer(1.0); // retry in 1 second + break; + + case F_TIMER: //Must be from listener port + if (!itsListener->isConnected()) { // still not connected? + itsListener->open(); // try again. + } break; - - default: - LOG_DEBUG(formatString("StartDaemon(%s)::initial_state, default",getName().c_str())); - status = GCFEvent::NOT_HANDLED; + + default: + LOG_DEBUG(formatString("LDStartDaemon(%s)::initial_state, default",getName().c_str())); + status = GCFEvent::NOT_HANDLED; break; } @@ -302,217 +128,97 @@ GCFEvent::TResult StartDaemon::initial_state(GCFEvent& event, GCFPortInterface& } // -// idle_state(event, port) +// operational_state(event, port) // -GCFEvent::TResult StartDaemon::idle_state(GCFEvent& event, GCFPortInterface& port) +// This is the normal operational mode. Wait for clients (e.g. MACScheduler) to +// connect, wait for commands from the clients and handle those. +// +GCFEvent::TResult LDStartDaemon::operational_state (GCFEvent& event, + GCFPortInterface& port) { - LOG_DEBUG(formatString("StartDaemon(%s)::idle_state (%s)",getName().c_str(),evtstr(event))); + LOG_DEBUG(formatString("LDStartDaemon(%s)::operational_state (%s)", + getName().c_str(),evtstr(event))); GCFEvent::TResult status = GCFEvent::HANDLED; + switch (event.signal) { - case F_INIT: + case F_INIT: break; - - case F_ENTRY: { - // open the server port to allow childs to connect - m_serverPort.open(); - break; - } - - case F_ACCEPT_REQ: { - boost::shared_ptr<TThePortTypeInUse> server(new TThePortTypeInUse); - server->init(*this, m_serverPortName, GCFPortInterface::SPP, STARTDAEMON_PROTOCOL); - m_serverPort.accept(*(server.get())); - m_childPorts.push_back(server); - break; - } - case F_DISCONNECTED: - _disconnectedHandler(port); + case F_ENTRY: { + break; + } + + case F_ACCEPT_REQ: { + GCFTCPPort* newClient = new GCFTCPPort; + newClient->init(*this, "client", GCFPortInterface::SPP, + STARTDAEMON_PROTOCOL); + itsListener->accept(*newClient); + itsClients.push_back(newClient); + break; + } + + case F_DISCONNECTED: + ASSERTSTR (&port != itsListener, "Listener port was closed, bailing out!"); + + handleClientDisconnect(port); + break; + + case F_CLOSED: + break; + + case F_TIMER: + break; + + case STARTDAEMON_CREATE: { + // [REO] On a schedule-event a LD is created??? + STARTDAEMONCreateEvent createEvent(event); + STARTDAEMONCreatedEvent createdEvent; + createdEvent.logicalDeviceType = createEvent.logicalDeviceType; + createdEvent.taskName = createEvent.taskName; + createdEvent.result = + itsStarter->createLogicalDevice (createEvent.logicalDeviceType, + createEvent.taskName, + createEvent.parentHost, + createEvent.parentService); + + port.send(createdEvent); + break; + } + + default: + LOG_DEBUG(formatString("LDStartDaemon(%s)::operational_state, default",getName().c_str())); + status = GCFEvent::NOT_HANDLED; break; - - case F_TIMER: { - GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); - // [REO] What happens if timer is NOT the garbageCollection timer? - if(timerEvent.id == m_garbageCollectionTimerId) { - LOG_DEBUG("Cleaning up the LogicalDevice garbage..."); - // garbage collection - TLogicalDeviceMap::iterator it = m_garbageCollection.begin(); - while(it != m_garbageCollection.end()) { - LOG_DEBUG(formatString("Destroying '%s'",it->first.c_str())); - m_garbageCollection.erase(it); - it = m_garbageCollection.begin(); - } - port.cancelTimer(timerEvent.id); - m_garbageCollectionTimerId = 0; - } - break; - } - - case STARTDAEMON_SCHEDULE: { - // [REO] On a schedule-event a LD is created??? - STARTDAEMONScheduleEvent scheduleEvent(event); - STARTDAEMONScheduledEvent scheduledEvent; - - scheduledEvent.result = createLogicalDevice( - scheduleEvent.logicalDeviceType, - scheduleEvent.taskName, - scheduleEvent.fileName); - - scheduledEvent.VIrootID = scheduleEvent.taskName; - - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(scheduledEvent.result)); - port.send(scheduledEvent); - break; - } - - case STARTDAEMON_DESTROY_LOGICALDEVICE: { - STARTDAEMONDestroyLogicaldeviceEvent destroyEvent(event); - STARTDAEMONDestroyLogicaldeviceEvent* pDestroyEvent = &destroyEvent; - if(destroyEvent.name.length() == 0) { - // the destroy event was sent from within this application, so it has - // not been packed. A static cast will do just fine. - pDestroyEvent = static_cast<STARTDAEMONDestroyLogicaldeviceEvent*>(&event); - } - - TSDResult result = SD_RESULT_UNSPECIFIED_ERROR; - if(pDestroyEvent != 0) { - result = destroyLogicalDevice(pDestroyEvent->name); - } - m_properties.setValue(SD_PROPNAME_STATUS,GCFPVInteger(result)); - break; - } - - case STARTDAEMON_STOP: { - stop(); - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(SD_RESULT_SHUTDOWN)); - break; - } - - default: - LOG_DEBUG(formatString("StartDaemon(%s)::idle_state, default",getName().c_str())); - status = GCFEvent::NOT_HANDLED; - break; } return (status); } // -// handlePropertySetAnswer(event) +// handleClientDisconnect(port) +// +// A disconnect event was receiveed on a client port. Close the port +// and remove the port from our pool. // -void StartDaemon::handlePropertySetAnswer(GCFEvent& answer) +void LDStartDaemon::handleClientDisconnect(GCFPortInterface& port) { - switch(answer.signal) { - case F_MYPS_ENABLED: { - GCFPropSetAnswerEvent* pPropAnswer = - static_cast<GCFPropSetAnswerEvent*>(&answer); - if(pPropAnswer->result == GCF_NO_ERROR) { - // property set loaded, now load apc? - } - else { - LOG_ERROR(formatString("%s : PropertySet %s NOT ENABLED", - getName().c_str(),pPropAnswer->pScope)); - } - break; - } + // end TCP connection + port.close(); - 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; - } + // cleanup connection in our pool + vector<GCFPortInterface*>::iterator iter = itsClients.begin(); + vector<GCFPortInterface*>::iterator theEnd = itsClients.end(); - case F_VCHANGEMSG: { - // check which property changed - GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer); - if ((pPropAnswer->pValue->getType() == LPT_STRING) && - (strstr(pPropAnswer->pPropName, SD_PROPNAME_COMMAND.c_str()) != 0)) { - // command received - string commandString(((GCFPVString*)pPropAnswer->pValue)->getValue()); - vector<string> parameters; - string command; - APLUtilities::decodeCommand(commandString,command,parameters); - - // SCHEDULE <type>,<taskname>,<filename> - if(command==string(SD_COMMAND_SCHEDULE)) { - if(parameters.size()==3) { - TLogicalDeviceTypes logicalDeviceType = - APLUtilities::convertLogicalDeviceType(parameters[0]); - string taskName = parameters[1]; - string fileName = parameters[2]; - - TSDResult result = createLogicalDevice (logicalDeviceType, - taskName, - fileName); - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(result)); - } - else { - TSDResult result = SD_RESULT_INCORRECT_NUMBER_OF_PARAMETERS; - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(result)); - } - return; - } - - // DESTROY_LOGICALDEVICE <name> - if(command==string(SD_COMMAND_DESTROY_LD)) { - if(parameters.size()==1) { - string name = parameters[0]; - - TSDResult result = destroyLogicalDevice(name); - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(result)); - } - else { - TSDResult result = SD_RESULT_INCORRECT_NUMBER_OF_PARAMETERS; - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(result)); - } - return; - } - - // STOP - if(command==string(SD_COMMAND_STOP)) { - m_properties.setValue(SD_PROPNAME_STATUS, - GCFPVInteger(SD_RESULT_SHUTDOWN)); - stop(); - return; - } - - TSDResult result = SD_RESULT_UNKNOWN_COMMAND; - m_properties.setValue(SD_PROPNAME_STATUS,GCFPVInteger(result)); - } // command received - break; - } - - default: - break; - } + while(iter != theEnd) { + if (*iter == &port) { + LOG_DEBUG_STR ("Erasing client port " << &port); + itsClients.erase(iter); + return; + } + } } -// -------------------- INLINE FUNCTIONS -------------------- - -// -// _isServerPort(GCFport) -// -bool StartDaemon::_isServerPort(GCFPortInterface& port) -{ - return (&port == &m_serverPort); // comparing two pointers. yuck? -} - - }; // namespace STSCtl + }; // namespace CUDaemons }; // namespace LOFAR diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.conf.in b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.conf.in index 32a627c8064a97e79380bd4e2dae62c83884ae65..6c996ccda39d4bd3f781c54786bde21070ac86ca 100644 --- a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.conf.in +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.conf.in @@ -1,9 +1,40 @@ -# new setup -OTDBusername = paulus -OTDBdatabasename = boskabouter -OTDBpassword = overeem -OTDBpollInterval = 5s - -QueuePeriod = 15m -ClaimPeriod = 2m +# Configuration file for the LDStartDaemon. +# +# Define the characteristics from the LogicalDevices the LDSD can start +# The sequencenumbers in the definition should be contiquous. +# +# Note: the types used in this list should correspond with the types +# defined in APL/APL/Common/APL_Defines.h +# +LogicalDevice.1.type = OBS_CTRL +LogicalDevice.1.program = ObservationControl +LogicalDevice.1.shared = false + +LogicalDevice.2.type = BEAMDIR_CTRL +LogicalDevice.2.program = BeamDirectionControl +LogicalDevice.2.shared = true + +LogicalDevice.3.type = GROUP_CTRL +LogicalDevice.3.program = RingControl +LogicalDevice.3.shared = true + +LogicalDevice.4.type = STS_CTRL +LogicalDevice.4.program = StationControl +LogicalDevice.4.shared = false + +LogicalDevice.5.type = DIGBOARD_CTRL +LogicalDevice.5.program = DigitalBoardControl +LogicalDevice.5.shared = false + +LogicalDevice.6.type = BEAM_CTRL +LogicalDevice.6.program = BeamControl +LogicalDevice.6.shared = true + +LogicalDevice.7.type = CAL_CTRL +LogicalDevice.7.program = CalibrationControl +LogicalDevice.7.shared = true + +LogicalDevice.8.type = STSINFRA_CTRL +LogicalDevice.8.program = StationInfraControl +LogicalDevice.8.shared = true diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.h b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.h new file mode 100644 index 0000000000000000000000000000000000000000..796e8f801495ee7accbed8b5b15c90815305b9ce --- /dev/null +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.h @@ -0,0 +1,67 @@ +//# LDStartDaemon.h: Server class that creates Logical Devices upon request. +//# +//# 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 CUDAEMONS_LDSTARTDAEMON_H +#define CUDAEMONS_LDSTARTDAEMON_H + +//# Includes +#include <Common/lofar_vector.h> +#include <GCF/TM/GCF_TCPPort.h> +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Event.h> +#include <APL/APLCommon/APL_Defines.h> +#include "LogicalDeviceStarter.h" + + +namespace LOFAR { + using namespace GCF::TM; + using namespace APLCommon; + namespace CUDaemons { + +class LDStartDaemon : public GCFTask +{ +public: + explicit LDStartDaemon(const string& name); + virtual ~LDStartDaemon(); + + // The state machines of the StartDaemon + GCFEvent::TResult initial_state (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult operational_state (GCFEvent& e, GCFPortInterface& p); + +protected: + // protected copy constructor + LDStartDaemon(const LDStartDaemon&); + LDStartDaemon& operator=(const LDStartDaemon&); + + void handleClientDisconnect(GCFPortInterface& port); + +private: + GCFTCPPort* itsListener; // listener for clients + uint32 itsListenRetryTimer;// retry itv for listener + vector<GCFPortInterface*> itsClients; // the command ports + LogicalDeviceStarter* itsStarter; // the starter object +}; + + }; // CUDaemons +}; // LOFAR + +#endif diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.log_prop.in b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.log_prop.in index b35aa3cc690bee061493b9c7559f67246024a52c..6ce0f73a7f4b9ee7216e04966b09ab6aea02549f 100644 --- a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.log_prop.in +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemon.log_prop.in @@ -3,12 +3,12 @@ log4cplus.rootLogger=DEBUG, STDOUT -log4cplus.logger.TRC=TRACE, STDOUT +log4cplus.logger.TRC=TRACE2, STDOUT 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} %-5p %c{9} - %m [%.25l]%n +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 diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemonMain.cc b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemonMain.cc index b5bf3b09b8f830ad3e83170bd003c36453bbec6e..9dae80eb75d07bb474315ce38fe4d5b121001dd0 100644 --- a/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemonMain.cc +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LDStartDaemonMain.cc @@ -1,4 +1,4 @@ -//# VirtualInstrumentStartDaemonMain.cc: Main entry for the VirtualInstrument start daemon +//# LDStartDaemon.cc: Main entry for the LogicalDevice startdaemon //# //# Copyright (C) 2002-2005 //# ASTRON (Netherlands Foundation for Research in Astronomy) @@ -19,38 +19,14 @@ //# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //# //# $Id$ -//#undef PACKAGE -//#undef VERSION #include <lofar_config.h> -#include <signal.h> #include <Common/LofarLogger.h> +#include <signal.h> -#include <boost/shared_ptr.hpp> -#include <APL/STSCtl/StartDaemon.h> -//#include "VirtualInstrument.h" -//#include "MaintenanceVI.h" -//#include "ObservationVI.h" -//#include <APL/ArrayReceptorGroup/ArrayReceptorGroup.h> -//#include <APL/ArrayOperations/ArrayOperations.h> -//#include <APL/VirtualRoute/VirtualRoute.h> -#ifdef CREATING_TASKS -#include <APL/STSCtl/LogicalDeviceFactory.h> -#include "LDtest.h" -#else -#include <APL/STSCtl/LDstarter.h> -#endif -//#include <APL/STSCtl/SharedLogicalDeviceFactory.h> +#include "LDStartDaemon.h" using namespace LOFAR; -using namespace LOFAR::STSCtl; using namespace LOFAR::GCF::Common; -using namespace LOFAR::GCF::TM; -using namespace LOFAR::GCF::PAL; -using namespace LOFAR::APLCommon; -//using namespace LOFAR::AVI; // A)pplication layer V)irtual I)nstrument -//using namespace LOFAR::AAO; // A)pplication layer A)rray O)perations -//using namespace LOFAR::AAR; // A)pplication layer A)rray R)eceptor group -//using namespace LOFAR::AVR; // A)pplication layer V)irtual R)oute int main(int argc, char* argv[]) { @@ -58,29 +34,7 @@ int main(int argc, char* argv[]) GCFTask::init(argc, argv); -#ifdef CREATING_TASKS - boost::shared_ptr<LogicalDeviceFactory<LDtest> > testFactory(new LogicalDeviceFactory<LDtest>); -#else - boost::shared_ptr<LDstarter> testFactory(new LDstarter("./LDtestMain")); -#endif - -// boost::shared_ptr<LogicalDeviceFactory<VirtualInstrument> > viFactory(new LogicalDeviceFactory<VirtualInstrument>); -// boost::shared_ptr<SharedLogicalDeviceFactory<ArrayReceptorGroup> > argFactory(new SharedLogicalDeviceFactory<ArrayReceptorGroup>); -// boost::shared_ptr<SharedLogicalDeviceFactory<ArrayOperations> > aoFactory(new SharedLogicalDeviceFactory<ArrayOperations>); -// boost::shared_ptr<LogicalDeviceFactory<VirtualRoute> > vrFactory(new LogicalDeviceFactory<VirtualRoute>); -// boost::shared_ptr<LogicalDeviceFactory<MaintenanceVI> > mviFactory(new LogicalDeviceFactory<MaintenanceVI>); -// boost::shared_ptr<LogicalDeviceFactory<ObservationVI> > oviFactory(new LogicalDeviceFactory<ObservationVI>); - - StartDaemon sd(string("VIC_VIStartDaemon")); // give myself a name - - sd.registerFactory(LDTYPE_VIRTUALINSTRUMENT,testFactory); - -// sd.registerFactory(LDTYPE_VIRTUALINSTRUMENT,viFactory); -// sd.registerFactory(LDTYPE_ARRAYRECEPTORGROUP,argFactory); -// sd.registerFactory(LDTYPE_ARRAYOPERATIONS,aoFactory); -// sd.registerFactory(LDTYPE_VIRTUALROUTE,vrFactory); -// sd.registerFactory(LDTYPE_MAINTENANCEVI,mviFactory); -// sd.registerFactory(LDTYPE_OBSERVATION,oviFactory); + CUDaemons::LDStartDaemon sd(string("StartDaemon")); // give myself a name sd.start(); // make initial transition diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LogicalDeviceStarter.cc b/MAC/APL/CUDaemons/src/CTStartDaemon/LogicalDeviceStarter.cc new file mode 100644 index 0000000000000000000000000000000000000000..f041623769c24c9699b874dea2d15d5df8b23a24 --- /dev/null +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LogicalDeviceStarter.cc @@ -0,0 +1,138 @@ +//# LogicalDeviceStarter.cc: one line description +//# +//# 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$ + +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> + +//# Includes +#include <Common/LofarLogger.h> +#include <sys/types.h> +#include <unistd.h> +#include <APL/APLCommon/StartDaemon_Protocol.ph> +#include "LogicalDeviceStarter.h" + +namespace LOFAR { + namespace CUDaemons { + +// +// LogicalDeviceStarter(executablename) +// +LogicalDeviceStarter::LogicalDeviceStarter(ParameterSet* aParSet) : + itsProgramList(), + itsError () +{ + string typeMask ("LogicalDevice.%d.type"); + string programMask("LogicalDevice.%d.program"); + string sharedMask ("LogicalDevice.%d.shared"); + LDstart_t startInfo; + + try { + for (uint32 counter = 1; ; counter++) { + string typeLabel (formatString(typeMask.c_str(), counter)); + string programLabel(formatString(programMask.c_str(), counter)); + string sharedLabel (formatString(sharedMask.c_str(), counter)); + startInfo.name = aParSet->getString(typeLabel); + startInfo.executable = aParSet->getString(programLabel); + startInfo.shared = aParSet->getBool (sharedLabel); + itsProgramList.push_back(startInfo); + } + } + catch (Exception& e) { + // expected throw: when counter > seqnr used in parameterSet. + } + + ASSERTSTR(itsProgramList.size() > 0, "No definition of LogicalDevice found " + "in the parameterSet."); + + LOG_DEBUG_STR("Found " << itsProgramList.size() << " LogicalDeviceTypes"); + +} + +// +// ~LogicalDeviceStarter +// +LogicalDeviceStarter::~LogicalDeviceStarter() +{ +} + +// +// createLogicalDevice(taskname, paramfile) +// +int32 LogicalDeviceStarter::createLogicalDevice(const string& ldTypeName, + const string& taskname, + const string& parentHost, + const string& parentService) +{ + uint32 nrDevices = itsProgramList.size(); + uint32 index(0); + while (index < nrDevices && itsProgramList[index].name.compare(ldTypeName)){ + index++; + } + if (index >= nrDevices) { + LOG_DEBUG_STR("No support for starting Logical Devices of the " + "type " << ldTypeName << ". See config file."); + return (SD_RESULT_UNSUPPORTED_LD); + } + + pid_t cid; + itsError = SD_RESULT_NO_ERROR; + + switch (cid = fork()) { + case -1: // error + itsError = errno; + LOG_FATAL_STR("fork() for task '" << taskname << + "' failed with errno: " << errno); + return (SD_RESULT_UNSPECIFIED_ERROR); + break; + + case 0: { // child + sleep (1); // give kernel and parent some time + setsid(); + LOG_DEBUG_STR("About to start: " << + itsProgramList[index].executable << + " " << taskname << " " << parentHost << + " " << parentService ); + + // Transform into the real program + int execError = execl(itsProgramList[index].executable.c_str(), + itsProgramList[index].executable.c_str(), + taskname.c_str(), + parentHost.c_str(), + parentService.c_str(), + 0L); + + LOG_FATAL_STR(getpid() << "Transform to " << + itsProgramList[index].executable << + " failed()!!! Errno=" << execError); + return (SD_RESULT_LD_NOT_FOUND); + break; + } + default: // parent + LOG_DEBUG_STR(getpid() << ": child process created: " << cid); + return (cid); // returning cid of child that will die soon. + break; + } +} + + + } // namespace CUDaemons +} // namespace LOFAR diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/LogicalDeviceStarter.h b/MAC/APL/CUDaemons/src/CTStartDaemon/LogicalDeviceStarter.h new file mode 100644 index 0000000000000000000000000000000000000000..46c0a1e6a0f5053d5f0947c1afca56c9585257fd --- /dev/null +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/LogicalDeviceStarter.h @@ -0,0 +1,82 @@ +//# LogicalDeviceStarter.h: one line description +//# +//# 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 LOFAR_CUDAEMONS_LOGICALDEVICESTARTER_H +#define LOFAR_CUDAEMONS_LOGICALDEVICESTARTER_H + +// \file +// one line description. + +//# Never #include <config.h> or #include <lofar_config.h> in a header file! + +//# Includes +#include <APS/ParameterSet.h> + +namespace LOFAR { + using ACC::APS::ParameterSet; + namespace CUDaemons { + + // \addtogroup CUDaemons + // @{ + + //# Forward Declarations + //#class forward; + + +// Description of class. +class LogicalDeviceStarter +{ +public: + explicit LogicalDeviceStarter (ParameterSet* aParSet); + ~LogicalDeviceStarter(); + + int32 createLogicalDevice (const string& ldTypeName, + const string& taskname, + const string& parentHost, + const string& parentService); + + int32 error() { return (itsError); } + +private: + // Copying is not allowed + LogicalDeviceStarter(); + LogicalDeviceStarter (const LogicalDeviceStarter& that); + LogicalDeviceStarter& operator= (const LogicalDeviceStarter& that); + +private: + //# Datamembers + typedef struct { + string name; + string executable; + bool shared; + } LDstart_t; + + vector<LDstart_t> itsProgramList; + int32 itsError; +}; + + // @} + + } // namespace CUDaemons +} // namespace LOFAR + +#endif diff --git a/MAC/APL/CUDaemons/src/CTStartDaemon/Makefile.am b/MAC/APL/CUDaemons/src/CTStartDaemon/Makefile.am index 906527e3362bf4d929d19825e5074cd1bc9e40ef..2fd3f32f820980d7092e694e55b15ec34849a382 100644 --- a/MAC/APL/CUDaemons/src/CTStartDaemon/Makefile.am +++ b/MAC/APL/CUDaemons/src/CTStartDaemon/Makefile.am @@ -1,3 +1,4 @@ +# Executables bin_PROGRAMS = LDStartDaemon LDStartDaemon_CPPFLAGS = -DBOOST_DISABLE_THREADS \ @@ -5,16 +6,19 @@ LDStartDaemon_CPPFLAGS = -DBOOST_DISABLE_THREADS \ -fmessage-length=0 \ -fdiagnostics-show-location=once -LDStartDaemon_SOURCES = LDStartDaemon.cc \ +LDStartDaemon_SOURCES = LogicalDeviceStarter.cc \ + LDStartDaemon.cc \ LDStartDaemonMain.cc -LDStartDaemon_LDADD = -lpqxx $(LOFAR_DEPEND) +LDStartDaemon_LDADD = $(LOFAR_DEPEND) LDStartDaemon_DEPENDENCIES = $(LOFAR_DEPEND) NOINSTHDRS = LDStartDaemon.h \ - LDStartDaemonDefines.h + LogicalDeviceStarter.h INSTHDRS = +BUILT_SOURCES = $(ph_HEADERS) + pkginclude_HEADERS = $(NOINSTHDRS) $(INSTHDRS) DOCHDRS = $(pkginclude_HEADERS) $(BUILT_SOURCES) diff --git a/MAC/APL/CUDaemons/test/EventPort.cc b/MAC/APL/CUDaemons/test/EventPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..3dd657c5b5188141983ec8ba1e8a3b3672a3c065 --- /dev/null +++ b/MAC/APL/CUDaemons/test/EventPort.cc @@ -0,0 +1,120 @@ +//# EventPort.cc: one line description +//# +//# 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$ + +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> + +//# Includes +#include <Common/LofarLogger.h> +#include <Common/StringUtil.h> +#include <Common/hexdump.h> +#include <GCF/TM/GCF_Event.h> +#include "EventPort.h" + +namespace LOFAR { + namespace CUdaemons { + +using GCF::TM::GCFEvent; + +// +// EventPort (host, port) +// +EventPort::EventPort(string aHostname, string aPort) : + itsPort(aPort), + itsHost(aHostname), + itsSocket(new Socket("EventSocket", itsHost, itsPort)) +{ + itsSocket->connect(-1); // try to connect, wait max 1 second + itsSocket->setBlocking(true); // no other tasks, do rest blocking +} + +// +// ~EventPort +// +EventPort::~EventPort() +{ + if (itsSocket) { + itsSocket->shutdown(); + delete itsSocket; + }; +} + +// +// send(Event*) +// +void EventPort::send(GCFEvent* anEvent) +{ + // Serialize the message and write buffer to port + uint32 packSize; + void* buf = anEvent->pack(packSize); + int32 btsWritten = itsSocket->write(buf, packSize); + ASSERTSTR(btsWritten == (int32)packSize, + "Only " << btsWritten << " of " << packSize << " bytes written"); +} + +// +// receive() : Event +// +GCFEvent* EventPort::receive() +{ + // First read header if answer: + // That is signal field + length field. + GCFEvent header; + int32 btsRead; + btsRead = itsSocket->read((void*) &header.signal, sizeof(header.signal)); + ASSERTSTR(btsRead == sizeof(header.signal), "Only " << btsRead << " of " + << sizeof(header.signal) << " bytes of header read"); + btsRead = itsSocket->read((void*) &header.length, sizeof(header.length)); + ASSERTSTR(btsRead == sizeof(header.length), "Only " << btsRead << " of " + << sizeof(header.length) << " bytes of header read"); + + LOG_DEBUG("Header received"); + + // Is there a payload in the message? This should be the case! + int32 remainingBytes = header.length; + LOG_DEBUG_STR(remainingBytes << " bytes to get next"); + if (remainingBytes <= 0) { + return(new GCFEvent); + } + + // create a buffer to receive the whole message + GCFEvent* fullAnswer = 0; + char* answerBuf = new char[sizeof(header) + remainingBytes]; + fullAnswer = (GCFEvent*) answerBuf; + + // copy received header + memcpy(answerBuf, &header, sizeof(header)); + + // read remainder + btsRead = itsSocket->read(answerBuf + sizeof(header), remainingBytes); + ASSERTSTR(btsRead == remainingBytes, + "Only " << btsRead << " bytes of msg read: " << remainingBytes); + + hexdump(fullAnswer, sizeof(header) + remainingBytes); + + // return Eventpointer + return (fullAnswer); +} + + + } // namespace CUdaemons +} // namespace LOFAR diff --git a/MAC/APL/CUDaemons/test/EventPort.h b/MAC/APL/CUDaemons/test/EventPort.h new file mode 100644 index 0000000000000000000000000000000000000000..0848d81ab3c81d68d8d8aec081bd2a37e09f2b9c --- /dev/null +++ b/MAC/APL/CUDaemons/test/EventPort.h @@ -0,0 +1,74 @@ +//# EventPort.h: one line description +//# +//# 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 LOFAR_STSCTL_EVENTPORT_H +#define LOFAR_STSCTL_EVENTPORT_H + +// \file +// one line description. + +//# Never #include <config.h> or #include <lofar_config.h> in a header file! + +//# Includes +#include <Common/Net/Socket.h> +#include <GCF/TM/GCF_Event.h> + +namespace LOFAR { + using GCF::TM::GCFEvent; + namespace CUdaemons { + +// \addtogroup CUdaemons +// @{ + +//# Forward Declarations +//class forward; + +// Description of class. +class EventPort +{ +public: + // Construct a port with a connection to a RSP driver on the given + // hostmachine. + EventPort(string aHostname, string aPort); + ~EventPort(); + + void send(GCFEvent* anEvent); + GCFEvent* receive(); + +private: + // Copying is not allowed + EventPort(); + EventPort (const EventPort& that); + EventPort& operator= (const EventPort& that); + + //# Datamembers + string itsPort; + string itsHost; + Socket* itsSocket; +}; + +// @} + + } // namespace CUdaemons +} // namespace LOFAR + +#endif diff --git a/MAC/APL/CUDaemons/test/LDtestMenu.cc b/MAC/APL/CUDaemons/test/LDtestMenu.cc new file mode 100644 index 0000000000000000000000000000000000000000..8074a63ecccc68ec30e7eacc595b9e87b86d02ab --- /dev/null +++ b/MAC/APL/CUDaemons/test/LDtestMenu.cc @@ -0,0 +1,129 @@ +//# LDtestMenu.cc: one line description +//# +//# 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$ + +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> + +//# Includes +#include <Common/LofarLogger.h> +#include "EventPort.h" +#include <APL/APLCommon/StartDaemon_Protocol.ph> +#include <APL/APLCommon/APL_Defines.h> + +using namespace LOFAR; +using namespace LOFAR::CUdaemons; + +static EventPort* SDport = 0; + +// +// doSchedule() +// +void doSchedule() { + STARTDAEMONCreateEvent event; + event.logicalDeviceType = LDTYPE_OBSERVATIONCTRL; + event.taskName = "testObservation"; + event.parentHost = "localHost"; + event.parentService = "MacScheduler:v1.0"; + + cout << "send request to create an ObservationController" << endl; + + SDport->send(&event); + GCFEvent* answer = SDport->receive(); + cout << "answer.length = " << answer->length << endl; +} + +// +// doKill() +// +void doKill() { + +} + +// +// doStop() +// +void doStop() { + +} + +// +// showMenu() +// +void showMenu() { + cout << endl << endl << endl; + cout << "Commands" << endl; + cout << "s Start LD" << endl; + cout << "k Kill LD" << endl; + cout << "S Stop StartDaemon(?)" << endl << endl; + + cout << "q Quit this program" << endl << endl; + + cout << "Enter the letter of your choice: "; +} + +// +// MAIN (param1, param2) +// +int main (int argc, char* argv[]) { + + // Always bring up the logger first + string progName = basename(argv[0]); + INIT_LOGGER (progName.c_str()); + + // Check invocation syntax + if (argc < 3) { + LOG_FATAL_STR ("Invocation error, syntax: " << progName << + " hostname portnr(startdaemon)"); + return (-1); + } + + SDport = new EventPort(argv[1], argv[2]); + + // Tell operator we are trying to start up. + LOG_INFO_STR("Starting up: " << argv[0] << "(" << argv[1] << ", " + << argv[2] << ")"); + try { + char aChoice = ' '; + while (aChoice != 'q') { + showMenu(); + cin.clear(); + cin >> aChoice; + switch (aChoice) { + case 's': doSchedule(); break; + case 'k': doKill(); break; + case 'S': doStop(); break; + } + } + + LOG_INFO_STR("Shutting down: " << argv[0]); + } + catch (LOFAR::Exception& ex) { + LOG_FATAL_STR("Caught exception: " << ex << endl); + LOG_FATAL_STR(argv[0] << " terminated by exception!"); + return (1); + } + + LOG_INFO_STR(argv[0] << " terminated normally"); + + return (0); + +} diff --git a/MAC/APL/CUDaemons/test/Makefile.am b/MAC/APL/CUDaemons/test/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..a0669e9ddc1db4f4bb63e6e2291b1b18d871018d --- /dev/null +++ b/MAC/APL/CUDaemons/test/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = -I$(top_builddir)/include + +bin_PROGRAMS = LDtestMenu ObservationControl + +LDtestMenu_SOURCES = EventPort.cc \ + LDtestMenu.cc +LDtestMenu_DEPENDENCIES = $(LOFAR_DEPEND) + +ObservationControl_SOURCES = dummyLD.cc +ObservationControl_DEPENDENCIES = $(LOFAR_DEPEND) + + +include $(top_srcdir)/Makefile.common diff --git a/MAC/APL/CUDaemons/test/Makefile.in b/MAC/APL/CUDaemons/test/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..51e13a71d77341f49da0f6ef5453e867f826c62b --- /dev/null +++ b/MAC/APL/CUDaemons/test/Makefile.in @@ -0,0 +1,763 @@ +# Makefile.in generated by automake 1.9.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Some common rules. + +SOURCES = $(LDtestMenu_SOURCES) $(ObservationControl_SOURCES) + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = LDtestMenu$(EXEEXT) ObservationControl$(EXEEXT) +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.common +subdir = test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/autoconf_share/am_rpm_init.m4 \ + $(top_srcdir)/autoconf_share/lofar_docxx.m4 \ + $(top_srcdir)/autoconf_share/lofar_external.m4 \ + $(top_srcdir)/autoconf_share/lofar_general.m4 \ + $(top_srcdir)/autoconf_share/lofar_init.m4 \ + $(top_srcdir)/autoconf_share/lofar_internal.m4 \ + $(top_srcdir)/autoconf_share/lofar_logger.m4 \ + $(top_srcdir)/autoconf_share/lofar_pvss.m4 \ + $(top_srcdir)/autoconf_share/lofar_qatools.m4 \ + $(top_srcdir)/autoconf_share/lofar_shmem.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_LDtestMenu_OBJECTS = EventPort.$(OBJEXT) LDtestMenu.$(OBJEXT) +LDtestMenu_OBJECTS = $(am_LDtestMenu_OBJECTS) +LDtestMenu_LDADD = $(LDADD) +am_ObservationControl_OBJECTS = dummyLD.$(OBJEXT) +ObservationControl_OBJECTS = $(am_ObservationControl_OBJECTS) +ObservationControl_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(LDtestMenu_SOURCES) $(ObservationControl_SOURCES) +DIST_SOURCES = $(LDtestMenu_SOURCES) $(ObservationControl_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AR_FLAGS = @AR_FLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCPP = @DOCPP@ +DOCPPFLAGS = @DOCPPFLAGS@ +DOXYGEN = @DOXYGEN@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +HAVE_APLCOMMON_FALSE = @HAVE_APLCOMMON_FALSE@ +HAVE_APLCOMMON_TRUE = @HAVE_APLCOMMON_TRUE@ +HAVE_APS_FALSE = @HAVE_APS_FALSE@ +HAVE_APS_TRUE = @HAVE_APS_TRUE@ +HAVE_COMMON_FALSE = @HAVE_COMMON_FALSE@ +HAVE_COMMON_TRUE = @HAVE_COMMON_TRUE@ +HAVE_DOCPP_FALSE = @HAVE_DOCPP_FALSE@ +HAVE_DOCPP_TRUE = @HAVE_DOCPP_TRUE@ +HAVE_DOXYGEN_FALSE = @HAVE_DOXYGEN_FALSE@ +HAVE_DOXYGEN_TRUE = @HAVE_DOXYGEN_TRUE@ +HAVE_GCFCOMMON_FALSE = @HAVE_GCFCOMMON_FALSE@ +HAVE_GCFCOMMON_TRUE = @HAVE_GCFCOMMON_TRUE@ +HAVE_GCFTM_FALSE = @HAVE_GCFTM_FALSE@ +HAVE_GCFTM_TRUE = @HAVE_GCFTM_TRUE@ +HAVE_LOG4CPLUS_FALSE = @HAVE_LOG4CPLUS_FALSE@ +HAVE_LOG4CPLUS_TRUE = @HAVE_LOG4CPLUS_TRUE@ +HAVE_PVSS_FALSE = @HAVE_PVSS_FALSE@ +HAVE_PVSS_TRUE = @HAVE_PVSS_TRUE@ +HAVE_SHMEM_FALSE = @HAVE_SHMEM_FALSE@ +HAVE_SHMEM_TRUE = @HAVE_SHMEM_TRUE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LOFARROOT = @LOFARROOT@ +LOFAR_DEPEND = @LOFAR_DEPEND@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MAKE_RPMS = @MAKE_RPMS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPMBUILD_PROG = @RPMBUILD_PROG@ +RPM_ARGS = @RPM_ARGS@ +RPM_CONFIGURE_ARGS = @RPM_CONFIGURE_ARGS@ +RPM_DIR = @RPM_DIR@ +RPM_PROG = @RPM_PROG@ +RPM_RELEASE = @RPM_RELEASE@ +RPM_TARBALL = @RPM_TARBALL@ +RPM_TARGET = @RPM_TARGET@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +docpp_found = @docpp_found@ +doxygen_dot_found = @doxygen_dot_found@ +doxygen_found = @doxygen_found@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +lofar_compiler = @lofar_compiler@ +lofar_doctool = @lofar_doctool@ +lofar_root = @lofar_root@ +lofar_root_libdir = @lofar_root_libdir@ +lofar_sharedir = @lofar_sharedir@ +lofar_top_srcdir = @lofar_top_srcdir@ +lofar_use_root = @lofar_use_root@ +lofar_variant = @lofar_variant@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +AM_CPPFLAGS = -I$(top_builddir)/include +LDtestMenu_SOURCES = EventPort.cc \ + LDtestMenu.cc + +LDtestMenu_DEPENDENCIES = $(LOFAR_DEPEND) +ObservationControl_SOURCES = dummyLD.cc +ObservationControl_DEPENDENCIES = $(LOFAR_DEPEND) +#CLEANFILES += tca.* .inslog* *.cc *.h $(top_builddir)/pure_cache docxxhtml/* *.log docxx_hdrs.names +DISTCLEANFILES = \ + pkgext\ + pkgextcppflags\ + pkgextcxxflags\ + pkgextobjs\ + lofar_config.old-h\ + lofar_config.h-pkg\ + lofar_config.h\ + .doxygenrc \ + *.spec \ + *.err + + +# Rules for building documentation using doxygen or doc++. +# Default output directory is docxxhtml. +DOCDIR := docxxhtml + +# +# +# Target to be able to do a system build. +# By default it does a check, but no install. +WITH_CLEAN = 0 +WITH_INSTALL = 0 +WITH_CHECK = 1 +CHECKTOOL = +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/Makefile.common $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign test/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +LDtestMenu$(EXEEXT): $(LDtestMenu_OBJECTS) $(LDtestMenu_DEPENDENCIES) + @rm -f LDtestMenu$(EXEEXT) + $(CXXLINK) $(LDtestMenu_LDFLAGS) $(LDtestMenu_OBJECTS) $(LDtestMenu_LDADD) $(LIBS) +ObservationControl$(EXEEXT): $(ObservationControl_OBJECTS) $(ObservationControl_DEPENDENCIES) + @rm -f ObservationControl$(EXEEXT) + $(CXXLINK) $(ObservationControl_LDFLAGS) $(ObservationControl_OBJECTS) $(ObservationControl_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EventPort.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LDtestMenu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummyLD.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-info-am + + +# CLEANFILES cannot delete directories, therefore use target clean-generic. +clean-generic: + -rm -rf ti_files + -rm -f tca.* + -rm -f .inslog* + -rm -f *.log + -rm -f *.i + -rm -f *.s + -rm -f src/*.h + -rm -f *.hh + -rm -f *.cc + -rm -f *.cs_cc + -rm -f doxygen.cfg + -rm -rf $(top_builddir)/pure_cache + -rm -rf docxxhtml + +# Make the rpm if possible. +# Note: +# MAKE_RPMS is set by lofar_init and possibly overwritten by lofar_general. +# Older package releases include Makefile.common from $lofar_sharedir +# with the effect that the include is handled by make. +# Newer releases (as of 1-11-2005) include Makefile.common from $top_srcdir +# with the effect that the include is handled by automake. +# To be compatible with older releases, it was decided that the MAKE_RPMS +# should be handled by make, hence the blank before endif. Otherwise +# automake complains about an endif without an if. + ifeq "$(MAKE_RPMS)" "true" + rpm: dist @RPM_TARGET@ + $(RPM_TARGET): $(DISTFILES) + ${MAKE} dist + -mkdir -p $(RPM_DIR)/SRPMS + -mkdir -p `dirname $(RPM_TARGET)` + $(RPM_PROG) $(RPM_ARGS) $(RPM_TARBALL) + @echo Congratulations, $(RPM_TARGET) "(and friends)" should now exist. + endif +# Put the phony target outside the if, otherwise automake gives +# warnings if a .PHONY is also defined in the Makefile.am. +.PHONY: rpm + +# Only preprocess the file. +%.i: %.cc + $(CXX) -E $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $< > $@ +%.i: %.c + $(CC) -E $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $< > $@ + +# Only compile (but not assemble) the file. +%.s: %.cc + $(CXX) -S $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $< +%.s: %.c + $(CC) -S $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $< + +# Rules for preprocessing idl files. +# There should be a corresponding .cc file in the source directory +# including the .cs_cc file. +%.cs_cc: %.idl + $(IDLCXX) $(IDLFLAGS) $(AM_IDLFLAGS) $< + echo '#include "$*_c.cc"' > $*.cs_cc + echo '#include "$*_s.cc"' >> $*.cs_cc + +# Rules for preprocessing Qt sources. +%.moc.cc: %.h + $(QT_DIR)/bin/moc $< -o $@ + +# Rule to build all test programs. +test: $(check_PROGRAMS) + +# Rule to build and run one or more test programs. +# The programs to build/run must be defined in the PGM variable. +checkrun: + @if [ "$(PGM)" = "" ] ; then \ + echo "Error: use as: make (mem)checkrun PGM=testprogram"; \ + else \ + curwd=`pwd`; \ + bcurwd=`basename $$curwd`; \ + if [ "$$bcurwd" != test ]; then \ + echo "Error: run (mem)checkrun in test directory"; \ + else \ + PGMT=; \ + for PGMVAR in $(PGM) ; \ + do \ + PGMTST=$$PGMVAR; \ + if [ -f $(srcdir)/$${PGMVAR}.sh ] ; then \ + PGMTST=$(srcdir)/$${PGMVAR}.sh; \ + elif [ -f $(srcdir)/$${PGMVAR}_test.sh ] ; then \ + PGMTST=$(srcdir)/$${PGMVAR}_test.sh; \ + fi; \ + PGMT="$$PGMT $$PGMTST"; \ + done; \ + echo "make check CHECKTOOL='$(CHECKTOOL)' check_PROGRAMS='$$PGM' TESTS='$$PGMT'"; \ + make check CHECKTOOL="$(CHECKTOOL)" check_PROGRAMS="$$PGM" TESTS="$$PGMT"; \ + fi \ + fi + +# Rule to run test programs using valgrind's memcheck tool. +memcheck: + @$(RM) `find . -name "*.valgrind.*"` + make check CHECKTOOL='valgrind --tool=memcheck --num-callers=50 --leak-check=yes --track-fds=yes --log-file=[PROGNAME].valgrind' + @vgfils=`find . -name "*.valgrind.*"`; \ + vgfils=`echo $$vgfils`; \ + nrvg=`echo "$$vgfils" | wc -w`; \ + nrvg=`echo $$nrvg`; \ + if [ "$$nrvg" != 0 -a "$$nrvg" != "" ]; then \ + echo ''; \ + echo "memcheck error summary from $$nrvg *.valgrind.* file(s)"; \ + echo '--------------------------------------------------'; \ + (grep "ERROR SUMMARY: " `echo $$vgfils` | grep -v " 0 errors ") || echo "No memory check errors"; \ + (grep "definitely lost: " `echo $$vgfils` | grep -v " 0 bytes ") || echo "No definite memory leaks"; \ + (grep "possibly lost: " `echo $$vgfils` | grep -v " 0 bytes ") || echo "No possible memory leaks"; \ + (grep " open file descriptor " `echo $$vgfils` | grep -v "descriptor [012]:") || echo "No file descriptor leaks"; \ + fi + +# Rule to build and run memcheck for one or more test programs. +# The programs to build/run must be defined in the PGM variable. +memcheckrun: + $(RM) `find . -name "*.valgrind.*"` + make checkrun CHECKTOOL='valgrind --tool=memcheck --num-callers=50 --leak-check=yes --track-fds=yes --log-file=[PROGNAME].valgrind' PGM="$(PGM)" + @vgfils=`find . -name "*.valgrind.*"`; \ + vgfils=`echo $$vgfils`; \ + nrvg=`echo "$$vgfils" | wc -w`; \ + nrvg=`echo $$nrvg`; \ + if [ "$$nrvg" != 0 -a "$$nrvg" != "" ]; then \ + echo ''; \ + echo "memcheckrun error summary from $$nrvg *.valgrind.* file(s)"; \ + echo '-----------------------------------------------------'; \ + (grep "ERROR SUMMARY: " `echo $$vgfils` | grep -v " 0 errors ") || echo "No memory check errors"; \ + (grep "definitely lost: " `echo $$vgfils` | grep -v " 0 bytes ") || echo "No definite memory leaks"; \ + (grep "possibly lost: " `echo $$vgfils` | grep -v " 0 bytes ") || echo "No possible memory leaks"; \ + (grep " open file descriptor " `echo $$vgfils` | grep -v "descriptor [012]:") || echo "No file descriptor leaks"; \ + fi + +doc: + @if [ "$(lofar_doctool)" = "doxygen" ] ; then \ + cp $(top_builddir)/.doxygenrc doxygen.cfg ; \ + projnm=`(cd $(srcdir) && pwd) | sed -e "s%.*/LOFAR/%%"` ; \ + echo "PROJECT_NAME = $$projnm" >> doxygen.cfg ; \ + echo "INPUT = $(srcdir)" >> doxygen.cfg ; \ + echo "RECURSIVE = YES" >> doxygen.cfg ; \ + echo "HTML_OUTPUT = $(DOCDIR)" >> doxygen.cfg ; \ + echo "EXCLUDE = $(srcdir)/build $(srcdir)/test $(srcdir)/demo" >> doxygen.cfg; \ + echo "GENERATE_TAGFILE = `basename $$projnm`.tag" >> doxygen.cfg ; \ + $(DOXYGEN) doxygen.cfg ; \ + else \ + if [ "$(lofar_doctool)" = "docpp" ] ; then \ + $(DOCPP) $(DOCPPFLAGS) --dir $(DOCDIR) `find $(srcdir) -name "*.h" -print` ; \ + else \ + echo "Error: No documentation tool configured" ; \ + fi \ + fi + +docthis: + @if [ "$(lofar_doctool)" = "doxygen" ] ; then \ + cp $(top_builddir)/.doxygenrc doxygen.cfg ; \ + projnm=`(cd $(srcdir) && pwd) | sed -e "s%.*/LOFAR/%%"` ; \ + echo "PROJECT_NAME = $$projnm" >> doxygen.cfg ; \ + echo "INPUT = $(srcdir)/src" >> doxygen.cfg ; \ + echo "RECURSIVE = NO" >> doxygen.cfg ; \ + echo "HTML_OUTPUT = $(DOCDIR)" >> doxygen.cfg ; \ + $(DOXYGEN) doxygen.cfg ; \ + else \ + if [ "$(lofar_doctool)" = "docpp" ] ; then \ + $(DOCPP) $(DOCPPFLAGS) --dir $(DOCDIR) $(srcdir)/*.h ; \ + else \ + echo "Error: No documentation tool configured" ; \ + fi \ + fi +build_system: + @if test 2 -eq $(WITH_CLEAN); then \ + $(MAKE) cleandist ; \ + ../../lofarconf; \ + fi; \ + if test 1 -eq $(WITH_CLEAN); then \ + $(MAKE) clean ; \ + fi; \ + $(MAKE); \ + if test 1 -eq $(WITH_CHECK); then \ + $(MAKE) check CHECKTOOL="$(CHECKTOOL)"; \ + fi; \ + if test 1 -eq $(WITH_INSTALL); then \ + $(MAKE) install ; \ + fi; + +# Show the important make variables. +show: + @echo "CXX = $(CXX)"; + @echo " `$(CXX) --version | head -1`"; + @echo "CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS)"; + @echo "CXXFLAGS = $(AM_CXXFLAGS) $(CXXFLAGS)"; + @echo "LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS)"; + @echo "LIBS = $(LIBS)"; + @echo "MPIBIN = $(MPIBIN)"; + @echo "AIPSPP = $(AIPSPP)"; + @echo "prefix = $(prefix)"; + +help: + @echo "make targets"; + @echo "------------"; + @echo "show show important make variables"; + @echo "pgm build test program pgm (in test directory)"; + @echo "test build all test programs"; + @echo "check build, run, and check all test programs"; + @echo "check CHECKTOOL= check test programs with a checktool (like valgrind)"; + @echo "memcheck check CHECKTOOL='valgrind --tool=memcheck" + @echo " --num-callers=50 --leak-check=yes --track-fds=yes'" + @echo "checkrun PGM= build, run, and check given test program(s)"; + @echo "memcheckrun PGM= build, run, and memcheck given test program(s)"; + @echo "" + @echo "file.o make object file (in src or test directory)"; + @echo "file.i make preprocessed file"; + @echo "file.s make assembly file"; + @echo "clean remove object files, etc." + @echo "cleandist remove almost everything; requires a new configure"; + @echo "install install package in $(prefix)"; + @echo "dist make a distribution"; + @echo "distcheck make and check a distribution"; + @echo "rpm make an rpm"; +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/MAC/APL/CUDaemons/test/dummyLD.cc b/MAC/APL/CUDaemons/test/dummyLD.cc new file mode 100644 index 0000000000000000000000000000000000000000..b555a4812d810046a9c9575f91f64ac36b7c0a03 --- /dev/null +++ b/MAC/APL/CUDaemons/test/dummyLD.cc @@ -0,0 +1,15 @@ +#include <lofar_config.h> +#include <stdio.h> + +int main (int argc, char* argv[]) +{ + printf ("Program invocation: "); + + for (int i = 0; i < argc; i++) { + printf ("%s ", argv[i]); + } + + printf ("\n"); + + return (1); +} diff --git a/MAC/APL/MainCU/configure.in b/MAC/APL/MainCU/configure.in index ee57a399b4e42652c5ec7aec3f9563c012672818..bb9f29c01a7849666f160b1b38057ed5c638fb8c 100644 --- a/MAC/APL/MainCU/configure.in +++ b/MAC/APL/MainCU/configure.in @@ -56,12 +56,12 @@ lofar_GENERAL lofar_COMPILETOOLS lofar_PVSS(1) lofar_INTERNAL(LCS/Common, common, LCS-Common-2_3, 1, Common/LofarTypes.h,,) -lofar_INTERNAL(LCS/ACC/APS, aps, LCS-ACC-2_0, 1, APS/ParameterSet.h,,) -lofar_INTERNAL(SAS/OTDB, otdb, HEAD, 1, OTDB/OTDBconnection.h,,) -lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, MAC-GCF-6_0, 1, GCF/GCF_Defines.h,,) -lofar_INTERNAL(MAC/GCF/TM, gcftm, MAC-GCF-6_0, 1, GCF/TM/GCF_Task.h,,) -lofar_INTERNAL(MAC/GCF/PAL, gcfpal, MAC-GCF-6_0, 1, GCF/PAL/GCF_PVSSInfo.h,,) -lofar_INTERNAL(MAC/APL/APLCommon, aplcommon, MAC-APL-3_1, 1, APL/APLCommon/APL_Defines.h,,) +lofar_INTERNAL(LCS/ACC/APS, aps, , 1, APS/ParameterSet.h,,) +lofar_INTERNAL(SAS/OTDB, otdb, , 1, OTDB/OTDBconnection.h,,) +lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, , 1, GCF/GCF_Defines.h,,) +lofar_INTERNAL(MAC/GCF/TM, gcftm, , 1, GCF/TM/GCF_Task.h,,) +lofar_INTERNAL(MAC/GCF/PAL, gcfpal, , 1, GCF/PAL/GCF_PVSSInfo.h,,) +lofar_INTERNAL(MAC/APL/APLCommon, aplcommon, , 1, APL/APLCommon/APL_Defines.h,,) lofar_EXTERNAL(boost,1.32,boost/date_time/date.hpp, boost_date_time-gcc) lofar_EXTERNAL(pqxx,2.5.5,pqxx/pqxx, pqxx) lofar_EXTERNAL(pq,,libpq-fe.h, pq, /usr/local/pgsql) diff --git a/MAC/APL/MainCU/src/MACScheduler/APLMACScheduler.dpl b/MAC/APL/MainCU/src/MACScheduler/APLMACScheduler.dpl index 18503e5533fc27fbb09830b85e5382a4771f29d1..763a416deb7f5ce262257c934522dbed15e29d7c 100644 --- a/MAC/APL/MainCU/src/MACScheduler/APLMACScheduler.dpl +++ b/MAC/APL/MainCU/src/MACScheduler/APLMACScheduler.dpl @@ -2,7 +2,7 @@ # DpType TypeName -TAplMacScheduler.TAplMacScheduler 1#1 +SwCntrl.MacScheduler 1#1 state 25#2 error 25#3 diff --git a/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc b/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc new file mode 100644 index 0000000000000000000000000000000000000000..923f4e15ddbb79521ee71d186a4f7e3176fd3f44 --- /dev/null +++ b/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc @@ -0,0 +1,683 @@ +//# ChildControl.cc: one line description +//# +//# 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$ + +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> + +//# Includes +#include <Common/LofarLogger.h> +#include <APS/ParameterSet.h> +#include <MainCU/MACScheduler/ChildControl.h> +#include <GCF/GCF_ServiceInfo.h> +#include <GCF/Utils.h> +#include <APL/APLCommon/APLUtilities.h> +#include <APL/APLCommon/LogicalDevice_Protocol.ph> +#include <APL/APLCommon/StartDaemon_Protocol.ph> + +namespace LOFAR { + using namespace GCF::TM; + using namespace APLCommon; + using namespace ACC::APS; + namespace MainCU { + +//-------------------------- creation and destroy --------------------------- + +ChildControl* ChildControl::instance() +{ + static ChildControl* theirChildControl; + + if (theirChildControl == 0) { + theirChildControl = new ChildControl(); + } + return (theirChildControl); +} + +// +// ChildControl() +// +ChildControl::ChildControl() : + GCFTask ((State)&ChildControl::initial, "ChildControl"), + itsListener (0), + itsStartDaemonMap (), + itsStartupRetryInterval (10), + itsMaxStartupRetries (5), + itsCntlrList (), + itsActionList () +{ + // Log the protocols I use. + registerProtocol(LOGICALDEVICE_PROTOCOL, LOGICALDEVICE_PROTOCOL_signalnames); + registerProtocol(STARTDAEMON_PROTOCOL, STARTDAEMON_PROTOCOL_signalnames); + + // adopt optional redefinition of startup-retry settings + if (globalParameterSet()->isDefined("ChildControl.StartupRetryInterval")) { + itsStartupRetryInterval = globalParameterSet()-> + getInt32("ChildControl.StartupRetryInterval"); + } + if (globalParameterSet()->isDefined("ChildControl.MaxStartupRetries")) { + itsStartupRetryInterval = globalParameterSet()-> + getInt32("ChildControl.MaxStartupRetries"); + } +} + +// +// ~ChildControl +// +ChildControl::~ChildControl() +{ + // close Listener + if (itsListener) { + itsListener->close(); + delete itsListener; + } + + // close all connections with the startDaemons. + map <string, GCFTCPPort*>::iterator iter = itsStartDaemonMap.begin(); + map <string, GCFTCPPort*>::const_iterator end = itsStartDaemonMap.end(); + while (iter != end) { + iter->second->close(); + iter++; + } + itsStartDaemonMap.clear(); + + // clear controller list. + itsCntlrList.clear(); + + // clear action list. + itsActionList.clear(); +} + +// +// openService(servicename, instanceNr) +// +// Starts the listener for the childs under the given name. +// +void ChildControl::openService(const string& aServiceName, + uint32 instanceNr) +{ + // can't set name only once + if (itsListener) { + return; + } + + itsListener = new GCFTCPPort(*this, aServiceName, GCFPortInterface::MSPP, + STARTDAEMON_PROTOCOL); + ASSERTSTR(itsListener, "Can't create a listener port for my children"); + + itsListener->setInstanceNr (instanceNr); + itsListener->open(); +} + +// +// startChild (name, obsId, aCntlType, hostname) +// +bool ChildControl::startChild (const string& aName, + OTDB::treeIDType anObsID, + const string& aCntlrType, + const string& hostname) +{ + // first check if child already exists + if (findController(aName) != itsCntlrList.end()) { + return (false); + } + + // Alright, child does not exist yet. + // construct structure with all information + ControllerInfo ci; + ci.name = aName; + ci.obsID = anObsID; + ci.cntlrType = aCntlrType; + ci.port = 0; + ci.hostname = hostname; + ci.requestedState = LDState::CONNECTED; + ci.requestTime = time(0); + ci.currentState = LDState::UNKNOWN; + ci.establishTime = 0; + ci.retryTime = 0; + ci.nrRetries = 0; + + // Update our administration. + itsCntlrList.push_back(ci); + + // Add it to the action list. + itsActionList.push_back(ci); + + // Trigger statemachine. + if (itsListener) { + itsActionTimer = itsListener->setTimer(0.0); + } + + LOG_TRACE_COND_STR ("Scheduled start of " << aName << " for obs " << anObsID); + + return (true); +} + +// +// requestState(state, [name], [observation], [type]) +// +// Sends a state-change request to the given child or childs. +// +bool ChildControl::requestState (LDState::LDstateNr aState, + const string& aName, + OTDB::treeIDType anObsID, + const string& aCntlrType) +{ + bool checkName = (aName != ""); + bool checkID = (anObsID != 0); + bool checkType = (aCntlrType != LDTYPE_NO_TYPE); + time_t currentTime = time(0); + +// stateChangeEvent request; +// request.newState = aState; +// request.time = currentTime; + + CIiter iter = itsCntlrList.begin(); + const_CIiter end = itsCntlrList.end(); + while (iter != end) { + // count the child when x has to be checked and matches: + // id==id checkID count_it + // Y Y Y + // Y N Y + // N Y N --> checkID && id!=id + // N N Y + if (!(checkName && iter->name != aName) && + !(checkID && iter->obsID != anObsID) && + !(checkType && iter->cntlrType != aCntlrType)) { + // send request to child + iter->requestedState = aState; + iter->requestTime = currentTime; +// iter->port.send(request); + } + + iter++; + } + + return (true); +} + +// +// getCurrentState(name) +// +// Returns the current state of the given controller. +// +LDState::LDstateNr ChildControl::getCurrentState (const string& aName) +{ + CIiter controller = findController(aName); + if (controller == itsCntlrList.end()) { + return (LDState::UNKNOWN); + } + + return (controller->currentState); +} + +// +// getRequestedState(name) +// +// Returns the requested state of the given controller. +// +LDState::LDstateNr ChildControl::getRequestedState (const string& aName) +{ + CIiter controller = findController(aName); + if (controller == itsCntlrList.end()) { + return (LDState::UNKNOWN); + } + + return (controller->requestedState); +} + +// +// countChilds([obsid],[cntlrtype]) +// +// Count the number of childs. The count can be limited to an +// observation or an controllertype or both. +// +uint32 ChildControl::countChilds (OTDB::treeIDType anObsID, + const string& aCntlrType) +{ + bool checkID = (anObsID != 0); + bool checkType = (aCntlrType != LDTYPE_NO_TYPE); + + if (!checkID && !checkType) { + return (itsCntlrList.size()); + } + + uint32 count = 0; + const_CIiter iter = itsCntlrList.begin(); + const_CIiter end = itsCntlrList.end(); + while (iter != end) { + if (!(checkID && iter->obsID != anObsID) && + !(checkType && iter->cntlrType != aCntlrType)) { + count++; + } + + iter++; + } + + return (count); +} + + +// +// getPendingRequest ([name], [observation], [type]) +// +// Returns a vector with all requests that are not confirmed by the +// childs. +// +vector<ChildControl::StateInfo> +ChildControl::getPendingRequest (const string& aName, + OTDB::treeIDType anObsID, + const string& aCntlrType) +{ + vector<ChildControl::StateInfo> resultVec; + + bool checkName = (aName != ""); + bool checkID = (anObsID != 0); + bool checkType = (aCntlrType != LDTYPE_NO_TYPE); + + const_CIiter iter = itsCntlrList.begin(); + const_CIiter end = itsCntlrList.end(); + while (iter != end) { + if (!(checkName && iter->name != aName) && + !(checkID && iter->obsID != anObsID) && + !(checkType && iter->cntlrType != aCntlrType) && + (iter->requestedState != iter->currentState)) { + // add info to vector + StateInfo si; + si.name = iter->name; + si.cntlrType = iter->cntlrType; + si.isConnected = (iter->port != 0); + si.requestedState = iter->requestedState; + si.requestTime = iter->requestTime; + si.currentState = iter->currentState; + si.establishTime = iter->establishTime; + resultVec.push_back(si); + } + iter++; + } + + return (resultVec); +} + +// -------------------- PRIVATE ROUTINES -------------------- + +// +// findController (name) +// +ChildControl::CIiter ChildControl::findController(const string& aName) +{ + CIiter iter = itsCntlrList.begin(); + const_CIiter end = itsCntlrList.end(); + + while (iter != end && iter->name != aName) { + iter++; + } + return (iter); +} + +// +// _processActionList() +// +// Walks through the actionlist and tries to process the actions. +// +void ChildControl::_processActionList() +{ + uint32 nrActions = itsActionList.size(); // prevents handling rescheduled actions + // when list is empty return; + if (!nrActions) { + return; + } + + LOG_TRACE_VAR_STR("Found " << nrActions << " actions in list"); + + // Walk through the action list + time_t currentTime = time(0); + CIiter action = itsActionList.begin(); + while (nrActions > 0) { + // don't process (rescheduled) action that lay in the future + if (action->retryTime > currentTime) { + itsActionList.push_back(*action); // add at back + action++; // hop to next + itsActionList.pop_front(); // remove at front. + nrActions--; // one less to handle. + continue; + } + + // search if corresponding controller exists + CIiter controller = findController(action->name); + if (controller == itsCntlrList.end()) { + LOG_WARN_STR("Controller " << action->name << + " not in administration, discarding request for state " << + action->requestedState); + action++; // hop to next + itsActionList.pop_front(); // remove 'handled' action. + nrActions--; // one less to handle. + continue; + } + + // found an action that should be handled now. + switch (action->requestedState) { + case LDState::CONNECTED: // start program, wait for CONNECTED msgs of child + { + // first check if connection if StartDaemon is made + SDiter startDaemon = itsStartDaemonMap.find(action->hostname); + if (startDaemon == itsStartDaemonMap.end() || + !startDaemon->second->isConnected()) { + LOG_TRACE_COND_STR("Startdaemon for " << action->hostname << + " not yet connected, defering startup command for " + << action->cntlrType << ":" << action->obsID); + // if not SDport at all for this host, create one first + if (startDaemon == itsStartDaemonMap.end()) { + itsStartDaemonMap[action->hostname] = new GCFTCPPort(*this, + MAC_SVCMASK_STARTDAEMON, + GCFPortInterface::SAP, + STARTDAEMON_PROTOCOL); + itsStartDaemonMap[action->hostname]->setHostName(action->hostname); + } + itsStartDaemonMap[action->hostname]->open(); + // leave action in list until connection with SD is made + itsActionList.push_back(*action); + break; + } + + // There is an connection with the startDaemon + if (action->nrRetries < itsMaxStartupRetries) { // retries left? + LOG_DEBUG_STR("Requesting start of " << action->name << " at " + << action->hostname); + STARTDAEMONCreateEvent startRequest; + startRequest.logicalDeviceType = action->cntlrType; + startRequest.taskName = action->name; + startRequest.parentHost = GCF::Common::myHostname(); + startRequest.parentService = itsListener->makeServiceName(); + startDaemon->second->send(startRequest); + + // we don't know if startup is successfull, reschedule startup + // over x seconds for safety. Note: when a succesfull startup + // is received the rescheduled action is removed. + action->retryTime = time(0) + itsStartupRetryInterval; + action->nrRetries++; + itsActionList.push_back(*action); // reschedule + } + else { + LOG_WARN_STR ("Could not start controller " << action->name << + " for observation " << action->obsID << + ", giving up."); + } + } + break; + + case LDState::CLAIMED: + { + LOGICALDEVICEClaimEvent request; + controller->port->send(request); + } + break; + + case LDState::PREPARED: + { + LOGICALDEVICEPrepareEvent request; + controller->port->send(request); + } + break; + + case LDState::RESUMED: + { + LOGICALDEVICEResumeEvent request; + controller->port->send(request); + } + break; + + case LDState::SUSPENDED: + { + LOGICALDEVICESuspendEvent request; + controller->port->send(request); + } + break; + + case LDState::RELEASED: + case LDState::FINISHED: + { + LOGICALDEVICEReleaseEvent request; + controller->port->send(request); + } + break; + + default: + ASSERTSTR(false, "Unhandled action: " << action->requestedState); + } + action++; // hop to next + itsActionList.pop_front(); // remove handled action. + nrActions--; // one less to handle. + } + + if (itsActionList.size()) { // when unhandled actions in list + itsActionTimer = itsListener->setTimer(1.0); // restart timer + } + +} + +// +// _removeAction (controller, requestedState) +// +void ChildControl::_removeAction (const string& aName, + LDState::LDstateNr requestedState) +{ + CIiter iter = itsActionList.begin(); + const_CIiter end = itsActionList.end(); + + while (iter != end) { + if (iter->name == aName && iter->requestedState == requestedState) { + itsActionList.erase(iter); + return; + } + iter++; + } + + return; +} + +// +// _setEstablishedState (name, state, time) +// +void ChildControl::_setEstablishedState(const string& aName, + LDState::LDstateNr newState, + time_t atTime) +{ + CIiter controller = findController(aName); + if (controller == itsCntlrList.end()) { + LOG_WARN_STR ("Could not update state of controller " << aName); + return; + } + + controller->currentState = newState; + controller->establishTime = atTime; +} + +// -------------------- STATE MACHINES FOR GCFTASK -------------------- + +// +// initial (event, port) +// +// Remember: there is nothing to do in the initial state until the user called +// 'openService' for our listener. After that service is called our task is to +// bring the listener alive. +// +GCFEvent::TResult ChildControl::initial (GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG ("ChildControl::initial"); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + break; + + case F_CONNECTED: + if (&port == itsListener) { + port.cancelAllTimers(); + LOG_DEBUG("Listener for children opened, going to operational state"); + TRAN (ChildControl::operational); + } + break; + + case F_DISCONNECTED: + if (&port == itsListener) { + port.setTimer(1.0); + } + else { +// _handleDisconnectEvent(event, port); + } + break; + + case F_TIMER: + // is this always the reconnect timer? + itsListener->open(); + break; + + default: + LOG_DEBUG_STR ("ChildControl(" << getName() << ")::initial, default"); + status = GCFEvent::NOT_HANDLED; + break; + } + + return (status); +} + +// +// operational (event, port) +// +// In the operational mode the users will request startup on new children (startChild) +// and state changes of existing children (requestState). +// +GCFEvent::TResult ChildControl::operational(GCFEvent& event, + GCFPortInterface& port) + +{ + LOG_DEBUG ("ChildControl::operational"); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + break; + + case F_ACCEPT_REQ: { + // Should be from a just started Child. + ASSERTSTR(port.getProtocol() == LOGICALDEVICE_PROTOCOL, + "AcceptReq on port " << port.getName()); + + // accept connection and add port to port-vector + GCFTCPPort* client(new GCFTCPPort); + // reminder: init (task, name, type, protocol [,raw]) + client->init(*this, "newChild", GCFPortInterface::SPP, + LOGICALDEVICE_PROTOCOL); + itsListener->accept(*client); + + // Note: we do not keep an administration of the accepted child + // sockets. Their ports will be in the ControllerList as soon as + // they have send a CONNECTED msg. + } + break; + + case F_CONNECTED: + break; + + case F_DISCONNECTED: { + CIiter controller = itsCntlrList.begin(); + CIiter end = itsCntlrList.end(); + while (controller != end) { + // search corresponding controller + if (controller->port != &port) { + controller++; + continue; + } + + // found controller, close port + port.close(); + if (controller->currentState == LDState::FINISHED) { // expected disconnect? + itsCntlrList.erase(controller); // just remove + } + else { + LOG_WARN_STR ("Lost connection with controller " << controller->name); + controller->port = 0; + // TODO: implement garbage collection + } + } + } + break; + + case F_TIMER: + itsActionTimer = 0; + _processActionList(); + break; + + case STARTDAEMON_CREATED: // startDaemon reports startup of program + { + STARTDAEMONCreatedEvent result(event); + LOG_DEBUG_STR("Startup of " << result.taskName << "ready, result=" + << result.result); + if (result.result == SD_RESULT_NO_ERROR) { + // startup is successfull, remove rescheduled startup. + _removeAction(result.taskName, LDState::CONNECTED); + } + // note: when startup of child failed the state is not updated and the + // parent will discover this when checking the pending requests. + } + break; + + case LOGICALDEVICE_CONNECT: + { + LOGICALDEVICEConnectEvent msg(event); + LOGICALDEVICEConnectedEvent answer; + + CIiter controller = findController(msg.nodeId); + if (controller == itsCntlrList.end()) { // not found? + LOG_WARN_STR ("CONNECT event received from unknown controller: " << + msg.nodeId); + answer.result = LD_RESULT_UNSPECIFIED; + } + else { + LOG_DEBUG_STR("CONNECT event received from " << msg.nodeId); + _setEstablishedState(msg.nodeId, LDState::CONNECTED, time(0)); + controller->port = &port; + answer.result = LD_RESULT_NO_ERROR; + } + port.send(answer); + } + break; + + default: + LOG_DEBUG_STR ("ChildControl(" << getName() << ")::operational, default"); + status = GCFEvent::NOT_HANDLED; + break; + } + + return (status); +} + + } // namespace MainCU +} // namespace LOFAR diff --git a/MAC/APL/MainCU/src/MACScheduler/ChildControl.h b/MAC/APL/MainCU/src/MACScheduler/ChildControl.h new file mode 100644 index 0000000000000000000000000000000000000000..f26d04ee24dc6787e0513ea4daa58f7775a0ffe1 --- /dev/null +++ b/MAC/APL/MainCU/src/MACScheduler/ChildControl.h @@ -0,0 +1,164 @@ +//# ChildControl.h: GCFTask for managing child controllers +//# +//# 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 MAINCU_CHILDCONTROL_H +#define MAINCU_CHILDCONTROL_H + +// \file +// GCFTask for managing child controllers + +//# Never #include <config.h> or #include <lofar_config.h> in a header file! +//# Includes +#include <Common/lofar_string.h> +#include <Common/lofar_map.h> +#include <Common/lofar_list.h> +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_TCPPort.h> +#include <APL/APLCommon/APL_Defines.h> +#include <OTDB/OTDBtypes.h> +#include "LDState.h" + +// Avoid 'using namespace' in headerfiles + +namespace LOFAR { + using GCF::TM::GCFTCPPort; + using GCF::TM::GCFEvent; + using GCF::TM::GCFTask; + using GCF::TM::GCFPortInterface; + using APLCommon::LDState; + namespace MainCU { + +// \addtogroup MainCU +// @{ + +//# --- Forward Declarations --- +//# classes mentioned as parameter or returntype without virtual functions. +//class ...; + + +// class_description +// ... +class ChildControl : public GCFTask +{ +public: + // the only way to create the object is via instance. + static ChildControl* instance(); + ~ChildControl(); + + typedef struct StateInfo_t { + string name; // uniq name of controller + string cntlrType; // controller type mnemonic + bool isConnected; // is attached to task + LDState::LDstateNr requestedState; // state the controller should reach + time_t requestTime; // time of requested state + LDState::LDstateNr currentState; // currrent (known) state of the controller + time_t establishTime; // time this state was reached + } StateInfo; + + // Assign a name to the service the task should offer to the childs + void openService (const string& aServiceName, + uint32 instanceNr = 0); + + // Functions to manage the child controllers + bool startChild (const string& aName, + OTDB::treeIDType anObsID, + const string& aCntlrType, + const string& hostname = "localhost"); + bool requestState (LDState::LDstateNr state, + const string& aName, + OTDB::treeIDType anObsID = 0, + const string& aCntlrType = LDTYPE_NO_TYPE); + uint32 countChilds (OTDB::treeIDType anObsID = 0, + const string& aCntlrType = LDTYPE_NO_TYPE); + + LDState::LDstateNr getCurrentState (const string& aName); + LDState::LDstateNr getRequestedState (const string& aName); + + // management info for creator of class. + vector<StateInfo> getPendingRequest (const string& aName, + OTDB::treeIDType anObsID = 0, + const string& aCntlrType = LDTYPE_NO_TYPE); + +private: + // Copying is not allowed + ChildControl(); + ChildControl(const ChildControl& that); + ChildControl& operator=(const ChildControl& that); + + // GCFTask statemachines + GCFEvent::TResult initial (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult operational (GCFEvent& event, GCFPortInterface& port); + + // Internal routines + void _processActionList(); + void _setEstablishedState (const string& aName, + LDState::LDstateNr newState, + time_t atTime); + void _removeAction (const string& aName, + LDState::LDstateNr requestedState); + + // Define struct for administration of the child controllers. + typedef struct ControllerInfo_t { + string name; // uniq name of the controller + OTDB::treeIDType obsID; // observation tree the cntlr belongs to + GCFPortInterface* port; // connection with the controller + string cntlrType; // type of controller (mnemonic) + string hostname; // host the controller runs on + LDState::LDstateNr requestedState; // the state the controller should have + time_t requestTime; // time of requested state + LDState::LDstateNr currentState; // the state the controller has + time_t establishTime; // time the current state was reached + time_t retryTime; // time the request must be retried + uint32 nrRetries; // nr of retries performed + } ControllerInfo; + typedef list<ControllerInfo>::iterator CIiter; + typedef list<ControllerInfo>::const_iterator const_CIiter; + CIiter findController(const string& name); + + //# --- Datamembers --- + GCFTCPPort* itsListener; // listener for child controllers + + map <string, GCFTCPPort*> itsStartDaemonMap; // map<hostname,sdconnection> + typedef map<string, GCFTCPPort*>::iterator SDiter; + typedef map<string, GCFTCPPort*>::const_iterator const_SDiter; + uint32 itsStartupRetryInterval; + uint32 itsMaxStartupRetries; + + list<ControllerInfo> itsCntlrList; // administration of child controller + + // All actions from the parent task are queued as ControllerInfo objects + // and handled in the operational stateMachine. + list<ControllerInfo> itsActionList; // list of actions to perform. + uint32 itsActionTimer; // ID of actiontimer. + +// ... + +}; + + +//# --- Inline functions --- + +// @} + } // namespace MainCU +} // namespace LOFAR + +#endif diff --git a/MAC/APL/MainCU/src/MACScheduler/LogicalDeviceState.cc b/MAC/APL/MainCU/src/MACScheduler/LDState.cc similarity index 77% rename from MAC/APL/MainCU/src/MACScheduler/LogicalDeviceState.cc rename to MAC/APL/MainCU/src/MACScheduler/LDState.cc index 527192bca73062472974c032101820583c813e9e..72830e57a4f81ac76c88338c63196a9f95c65d58 100644 --- a/MAC/APL/MainCU/src/MACScheduler/LogicalDeviceState.cc +++ b/MAC/APL/MainCU/src/MACScheduler/LDState.cc @@ -1,4 +1,4 @@ -//# LogicalDeviceState.cc: one_line_description +//# LDState.cc: one_line_description //# //# Copyright (C) 2002-2004 //# ASTRON (Netherlands Foundation for Research in Astronomy) @@ -25,24 +25,20 @@ //# Includes #include <Common/LofarLogger.h> -#include <LogicalDeviceState.h> +#include <LDState.h> namespace LOFAR { namespace APLCommon { // -// LogicalDeviceState() +// LDState() // -LogicalDeviceState::LogicalDeviceState() +LDState::LDState() { itsStates.resize(LAST_STATE); itsStates[UNKNOWN] = "Unknown"; itsStates[CONNECT] = "Connecting"; itsStates[CONNECTED] = "Connected"; - itsStates[SCHEDULE] = "Scheduling"; - itsStates[SCHEDULED] = "Scheduled"; - itsStates[CANCEL_SCHEDULE] = "Canceling Schedule"; - itsStates[SCHEDULE_CANCELLED] = "Schedule Cancelled"; itsStates[CLAIM] = "Claiming"; itsStates[CLAIMED] = "Claimed"; itsStates[PREPARE] = "Preparing"; @@ -58,19 +54,25 @@ LogicalDeviceState::LogicalDeviceState() } // -// ~LogicalDeviceState() +// ~LDState() // -LogicalDeviceState::~LogicalDeviceState() +LDState::~LDState() { } -string LogicalDeviceState::name(uint16 aStateNr) +// +// name(statenr) +// +string LDState::name(uint16 aStateNr) { return (((aStateNr >= UNKNOWN) && (aStateNr < LAST_STATE)) ? itsStates[aStateNr] : ""); } -uint16 LogicalDeviceState::value(const string& aStateName) +// +// value(name) +// +uint16 LDState::value(const string& aStateName) { uint16 i = UNKNOWN; while (i < LAST_STATE) { @@ -80,7 +82,18 @@ uint16 LogicalDeviceState::value(const string& aStateName) i++; } - ASSERTSTR(false, aStateName << " is not a valid LogicalDeviceState"); + ASSERTSTR(false, aStateName << " is not a valid LDState"); +} + +// +// value(LDstateNr) +// +uint16 LDState::value(LDstateNr aStateNr) +{ + ASSERTSTR((aStateNr >= UNKNOWN) && (aStateNr < LAST_STATE), + aStateNr << " is not a valid LDState"); + + return ((uint16) aStateNr); } } // namespace APL diff --git a/MAC/APL/MainCU/src/MACScheduler/LogicalDeviceState.h b/MAC/APL/MainCU/src/MACScheduler/LDState.h similarity index 79% rename from MAC/APL/MainCU/src/MACScheduler/LogicalDeviceState.h rename to MAC/APL/MainCU/src/MACScheduler/LDState.h index 69c55120a8a409b03461ffb90652170961a7c104..3bed649785fa03aac562f6dedb10158e7197fdb6 100644 --- a/MAC/APL/MainCU/src/MACScheduler/LogicalDeviceState.h +++ b/MAC/APL/MainCU/src/MACScheduler/LDState.h @@ -1,4 +1,4 @@ -//# LogicalDeviceState.h: one_line_description +//# LDState.h: one_line_description //# //# Copyright (C) 2002-2004 //# ASTRON (Netherlands Foundation for Research in Astronomy) @@ -23,7 +23,7 @@ #ifndef APL_LOGICALDEVICESTATE_H #define APL_LOGICALDEVICESTATE_H -// \file LogicalDeviceState.h +// \file LDState.h // one_line_description //# Never #include <config.h> or #include <lofar_config.h> in a header file! @@ -41,21 +41,17 @@ namespace LOFAR { // class_description // ... -class LogicalDeviceState +class LDState { public: - LogicalDeviceState(); - ~LogicalDeviceState(); + LDState(); + ~LDState(); // define enumeration for all states of an LogicalDevice. typedef enum { UNKNOWN = 0, CONNECT, CONNECTED, - SCHEDULE, - SCHEDULED, - CANCEL_SCHEDULE, - SCHEDULE_CANCELLED, CLAIM, CLAIMED, PREPARE, @@ -72,8 +68,9 @@ public: } LDstateNr; // conversion routines - string name(uint16 aStateNr); + string name (uint16 aStateNr); uint16 value(const string& aStateName); + uint16 value(LDstateNr aStateNr); // ... example ostream& print (ostream& os) const @@ -81,8 +78,8 @@ public: private: // Copying is not allowed - LogicalDeviceState(const LogicalDeviceState& that); - LogicalDeviceState& operator=(const LogicalDeviceState& that); + LDState(const LDState& that); + LDState& operator=(const LDState& that); //# --- Datamembers --- vector<string> itsStates; @@ -94,9 +91,9 @@ private: //# //# operator<< //# -inline ostream& operator<< (ostream& os, const LogicalDeviceState& aLogicalDeviceState) +inline ostream& operator<< (ostream& os, const LDState& aLDState) { - return (aLogicalDeviceState.print(os)); + return (aLDState.print(os)); } diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc index 510e7468952af04bbc811dc95ed100e01a8c9a4a..01120ff9208c7c02f9008e5b6e6e25cce2a202ec 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc @@ -24,14 +24,14 @@ #include <boost/shared_array.hpp> #include <APS/ParameterSet.h> +#include <GCF/GCF_ServiceInfo.h> #include <GCF/GCF_PVString.h> #include <GCF/GCF_PVDouble.h> #include <GCF/GCF_PVInteger.h> #include <GCF/PAL/GCF_PVSSInfo.h> +#include <GCF/Utils.h> +#include <APL/APLCommon/APLCommonExceptions.h> -#include "APL/APLCommon/APLUtilities.h" -#include "APL/APLCommon/APLCommonExceptions.h" -#include <LogicalDeviceState.h> #include "MACSchedulerDefines.h" #include "MACScheduler.h" @@ -44,7 +44,7 @@ using namespace std; namespace LOFAR { using namespace APLCommon; using namespace ACC::APS; - namespace MCU { + namespace MainCU { // // MACScheduler() @@ -54,17 +54,10 @@ MACScheduler::MACScheduler() : PropertySetAnswerHandlerInterface(), itsPropertySetAnswer(*this), itsPropertySet (), -// itsVISDclientPorts (), -// itsVIparentPortName (string("VIparent_server")), -// itsVIparentPort (*this, m_VIparentPortName, GCFPortInterface::MSPP, LOGICALDEVICE_PROTOCOL), -// itsVIclientPorts (), -// itsconnectedVIclientPorts(), - - itsObsCntlrMap (), - itsSDclientPort (0), - itsLDserverPort (0), +// itsObsCntlrMap (), + itsDummyPort (0), + itsChildControl (0), itsSecondTimer (0), - itsSDretryTimer (0), itsQueuePeriod (0), itsClaimPeriod (0), itsOTDBconnection (0), @@ -77,14 +70,13 @@ MACScheduler::MACScheduler() : LOG_WARN("Using GCFTCPPort in stead of GCFPVSSPort"); #endif - // Log the protocols I use. - registerProtocol(LOGICALDEVICE_PROTOCOL, LOGICALDEVICE_PROTOCOL_signalnames); - registerProtocol(STARTDAEMON_PROTOCOL, STARTDAEMON_PROTOCOL_signalnames); - // Readin some parameters from the ParameterSet. itsOTDBpollInterval = globalParameterSet()->getTime("OTDBpollInterval"); itsQueuePeriod = globalParameterSet()->getTime("QueuePeriod"); itsClaimPeriod = globalParameterSet()->getTime("ClaimPeriod"); + + // get pointer to childcontrol task + itsChildControl = ChildControl::instance(); } @@ -103,10 +95,6 @@ MACScheduler::~MACScheduler() if (itsOTDBconnection) { delete itsOTDBconnection; } - if (itsSDclientPort) { - itsSDclientPort->close(); - delete itsSDclientPort; - } } @@ -177,14 +165,19 @@ void MACScheduler::handlePropertySetAnswer(GCFEvent& answer) // GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& /*port*/) { + LOG_DEBUG ("MACScheduler::initial_state"); + GCFEvent::TResult status = GCFEvent::HANDLED; switch (event.signal) { - case F_INIT: + case F_INIT: + LOG_TRACE_FLOW("initial_state:F_INIT"); break; - case F_ENTRY: { + case F_ENTRY: { + LOG_TRACE_FLOW("initial_state:F_ENTRY"); // Get access to my own propertyset. + LOG_DEBUG ("Activating PropertySet"); itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(MS_PROPSET_NAME, MS_PROPSET_TYPE, PS_CAT_PERMANENT, @@ -192,6 +185,7 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& itsPropertySet->enable(); // update PVSS. + LOG_TRACE_FLOW ("Updateing state to PVSS"); itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("initial")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); @@ -201,44 +195,35 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& string DBname = pParamSet->getString("OTDBdatabasename"); string password = pParamSet->getString("OTDBpassword"); - itsOTDBconnection= new OTDBconnection(username, DBname, password); + LOG_DEBUG ("Trying to connect to the OTDB"); + itsOTDBconnection= new OTDBconnection(username, password, DBname); ASSERTSTR (itsOTDBconnection, "Memory allocation error (OTDB)"); ASSERTSTR (itsOTDBconnection->connect(), "Unable to connect to database " << DBname << " using " << username << "," << password); + LOG_INFO ("Connected to the OTDB"); - // Connect to local startDaemon - itsSDclientPort = new GCFTCPPort(*this, - "StartDaemon", - GCFPortInterface::SAP, - STARTDAEMON_PROTOCOL); - ASSERTSTR(itsSDclientPort, "Unable to allocate a port for the StartDaemon"); - itsSDclientPort->open(); // may result in CONN or DISCONN event - } - break; + // Start ChildControl task + LOG_DEBUG ("Enabling ChildControltask"); + itsChildControl->openService(MAC_SVCMASK_SCHEDULERCTRL, 0); - case F_CONNECTED: // must be from SDclient port. - if (itsSDclientPort->isConnected()) { // connected with SD! - itsSDclientPort->cancelTimer(itsSDretryTimer); // cancel retry timer - TRAN(MACScheduler::recover_state); // go to next state. + // need port for timers(!) + itsDummyPort = new GCFTimerPort(*this, "MACScheduler:dummy4timers"); + TRAN(MACScheduler::recover_state); // go to next state. } break; +#if 0 + case F_CONNECTED: + break; - case F_DISCONNECTED: // must be from SDclient port. - if (!itsSDclientPort->isConnected()) { // connection with SD failed - // tell PVSS what my problem is - itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR), + case F_DISCONNECTED: + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR), GCFPVString("Waiting for StartDaemon")); - itsSDretryTimer = itsSDclientPort->setTimer(1.0); // retry in 1 second. - } break; - case F_TIMER: // must be from SDclient port. - if (!itsSDclientPort->isConnected()) { // really not connected? - itsSDclientPort->open(); // try again - } + case F_TIMER: break; - +#endif default: LOG_DEBUG_STR ("MACScheduler(" << getName() << ")::initial_state, default"); status = GCFEvent::NOT_HANDLED; @@ -256,6 +241,8 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& port) { + LOG_DEBUG ("MACScheduler::recover_state"); + GCFEvent::TResult status = GCFEvent::HANDLED; switch (event.signal) { @@ -267,13 +254,6 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("recover")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); - // open server port for ObservationControllers - itsLDserverPort = new GCFTCPPort(*this, - "ObsControllers", - GCFPortInterface::MSPP, - LOGICALDEVICE_PROTOCOL); - itsLDserverPort->open(); // LDprotocol server port - // // TODO: do recovery @@ -298,6 +278,8 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& port) { + LOG_DEBUG ("MACScheduler::active_state"); + GCFEvent::TResult status = GCFEvent::HANDLED; switch (event.signal) { @@ -310,25 +292,12 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); // Timers must be connected to ports, so abuse serverPort for second timer. - itsSecondTimer = itsLDserverPort->setTimer(1L); + itsSecondTimer = itsDummyPort->setTimer(1L); break; } - case F_ACCEPT_REQ: { - // Should be from a just started ObservationController. - ASSERTSTR(port.getProtocol() == LOGICALDEVICE_PROTOCOL, - "AcceptReq on port " << port.getName()); - - - // accept connection and add port to port-vector - GCFTCPPort* client(new GCFTCPPort); - // reminder: init (task, name, type, protocol [,raw]) - client->init(*this, "newObsCntlr", GCFPortInterface::SPP, - LOGICALDEVICE_PROTOCOL); - itsLDserverPort->accept(*client); - itsObsCntlrPorts.push_back(client); // save client port in stack + case F_ACCEPT_REQ: break; - } case F_CONNECTED: // Should be from the (lost) connection with the SD @@ -348,8 +317,10 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& // time to poll the OTDB? if (time(0) >= itsNextOTDBpolltime) { _doOTDBcheck(); - // reinit polltime. + // reinit polltime at multiple of intervaltime. + // (=more change to hit hh.mm:00) itsNextOTDBpolltime = time(0) + itsOTDBpollInterval; + itsNextOTDBpolltime -= (itsNextOTDBpolltime % itsOTDBpollInterval); } itsSecondTimer = port.setTimer(1.0); } @@ -362,30 +333,6 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& break; } - case LOGICALDEVICE_CONNECT: { - // An ObsCntlr has started and reports that it is started - LOGICALDEVICEConnectEvent connectEvent(event); - GCFTCPPort* portPtr(static_cast<GCFTCPPort*>(&port)); - - // copy name of controller to portname - // does not exist! portPtr->setName(connectEvent.nodeId); - - // construct a controller object. - ObsCntlr_t controller; - controller.treeID = atol(connectEvent.nodeId.c_str()); - controller.port = portPtr; - controller.state = LogicalDeviceState::CONNECTED; - - // add it to the map - // TODO: - - // report to ObsCntlr that he is registered. - LOGICALDEVICEConnectedEvent connectedEvent; - connectedEvent.result = LD_RESULT_NO_ERROR; - port.send(connectedEvent); - break; - } - case LOGICALDEVICE_SCHEDULED: { LOGICALDEVICEScheduledEvent scheduledEvent(event); // ... @@ -398,49 +345,6 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& break; } - case LOGICALDEVICE_CLAIMED: { - LOGICALDEVICEClaimedEvent claimedEvent(event); - // ... - break; - } - - case LOGICALDEVICE_PREPARED: { - LOGICALDEVICEPreparedEvent preparedEvent(event); - // ... - break; - } - - case LOGICALDEVICE_RESUMED: { - LOGICALDEVICEResumedEvent resumedEvent(event); - // ... - break; - } - - case LOGICALDEVICE_SUSPENDED: { - LOGICALDEVICESuspendedEvent suspendedEvent(event); - // ... - break; - } - - case LOGICALDEVICE_RELEASED: { - LOGICALDEVICEReleasedEvent releasedEvent(event); - // ... - break; - } - - case LOGICALDEVICE_FINISH: { - LOGICALDEVICEFinishEvent finishEvent(event); - // ... - break; - } - - case STARTDAEMON_SCHEDULED: - { - STARTDAEMONScheduledEvent scheduledEvent(event); - // ... - break; - } - default: LOG_DEBUG(formatString("MACScheduler(%s)::active_state, default", getName().c_str())); @@ -459,6 +363,67 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& // void MACScheduler::_doOTDBcheck() { + // get new list (list is ordered on starttime) + vector<OTDBtree> newTreeList = itsOTDBconnection->getExecutableTrees(); + if (newTreeList.empty()) { + return; + } + + LOG_DEBUG(formatString("OTDBCheck:First observation is at %s (tree=%d)", + to_simple_string(newTreeList[0].starttime).c_str(), newTreeList[0].treeID())); + + // walk through the list and bring each observation in the right state when necc. + uint32 listSize = newTreeList.size(); + uint32 idx = 0; + ptime currentTime = from_time_t(time(0)); + ASSERTSTR (currentTime != not_a_date_time, "Can't determine systemtime, bailing out"); + + // REO: test pvss appl + itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString(to_simple_string(currentTime))); + + while (idx < listSize) { + // timediff = time to go before start of Observation + time_duration timediff = newTreeList[idx].starttime - currentTime; + LOG_TRACE_VAR_STR("timediff=" << timediff); + + // when queuetime is not reached yet were are finished with the list. + if (timediff > seconds(itsQueuePeriod)) { + break; + } + + // get current state of Observation + string cntlrName = formatString("ObsCntlr_%d", newTreeList[idx].treeID()); + LDState::LDstateNr observationState = itsChildControl->getRequestedState(cntlrName); + + // remember: timediff <= queueperiod + if (timediff > seconds(itsClaimPeriod)) { + // Observation is somewhere in the queueperiod + if (observationState != LDState::CONNECTED) { + itsChildControl->startChild(cntlrName, + newTreeList[idx].treeID(), + LDTYPE_OBSERVATIONCTRL, + myHostname()); + idx++; + continue; + } + } + + if (timediff > seconds(0)) { + // Observation is somewhere in the claim period + if (observationState != LDState::CLAIMED) { +// _claimObservation(&newTreeList[idx]); + idx++; + continue; + } + } + + // observation must be running (otherwise it would not be in the newTreeList) + if (observationState != LDState::RESUMED) { +// _executeObservation(&newTreeList[idx]); + } + + idx++; + } } diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in index a52cc088449119470257f3b21c4ca92cf55c6486..34b6540dbdd9bfd4df9d3435fd8c4d111a30c5c7 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in @@ -1,53 +1,13 @@ -mac.ns.MACScheduler.SAS_server.type=TCP -mac.ns.MACScheduler.SAS_server.host=lofar27 -mac.ns.MACScheduler.SAS_server.port=27000 -mac.ns.MACScheduler.VIparent_server.type=TCP -mac.ns.MACScheduler.VIparent_server.host=lofar27 -mac.ns.MACScheduler.VIparent_server.port=27100 - -mac.ns.CCU1_VIC_VIStartDaemon.server.type=TCP -mac.ns.CCU1_VIC_VIStartDaemon.server.host=lofar27 -mac.ns.CCU1_VIC_VIStartDaemon.server.port=27010 -mac.top.MACScheduler.CCU1_VIC_VIStartDaemon.remoteservice=CCU1_VIC_VIStartDaemon:server -mac.ns.CCU2_VIC_VIStartDaemon.server.type=TCP -mac.ns.CCU2_VIC_VIStartDaemon.server.host=ccu2 -mac.ns.CCU2_VIC_VIStartDaemon.server.port=27010 -mac.top.MACScheduler.CCU2_VIC_VIStartDaemon.remoteservice=CCU2_VIC_VIStartDaemon:server -mac.ns.CCU3_VIC_VIStartDaemon.server.type=TCP -mac.ns.CCU3_VIC_VIStartDaemon.server.host=ccu3 -mac.ns.CCU3_VIC_VIStartDaemon.server.port=27010 -mac.top.MACScheduler.CCU3_VIC_VIStartDaemon.remoteservice=CCU3_VIC_VIStartDaemon:server -mac.ns.CCU4_VIC_VIStartDaemon.server.type=TCP -mac.ns.CCU4_VIC_VIStartDaemon.server.host=ccu4 -mac.ns.CCU4_VIC_VIStartDaemon.server.port=27010 -mac.top.MACScheduler.CCU4_VIC_VIStartDaemon.remoteservice=CCU4_VIC_VIStartDaemon:server -mac.ns.CCU5_VIC_VIStartDaemon.server.type=TCP -mac.ns.CCU5_VIC_VIStartDaemon.server.host=ccu5 -mac.ns.CCU5_VIC_VIStartDaemon.server.port=27010 -mac.top.MACScheduler.CCU5_VIC_VIStartDaemon.remoteservice=CCU5_VIC_VIStartDaemon:server -mac.ns.CCU6_VIC_VIStartDaemon.server.type=TCP -mac.ns.CCU6_VIC_VIStartDaemon.server.host=ccu6 -mac.ns.CCU6_VIC_VIStartDaemon.server.port=27010 -mac.top.MACScheduler.CCU6_VIC_VIStartDaemon.remoteservice=CCU6_VIC_VIStartDaemon:server - # new setup +OTDBdatabasename = overeem OTDBusername = paulus -OTDBdatabasename = boskabouter -OTDBpassword = overeem +OTDBpassword = boskabouter OTDBpollInterval = 5s QueuePeriod = 15m ClaimPeriod = 2m +# next parameters are optional, defaultvalues are shown +#ChildControl.StartupRetryInterval = 10s +#ChildControl.MaxStartupRetry = 5 -# -# should be obsolete -# -shareLocation=/opt/lofar/MAC/parametersets/ - -# -# Obsolete -# -#mac.apl.ams.CCU2.startDaemonHost=earth -#mac.apl.ams.CCU2.startDaemonPort=server -#mac.apl.ams.CCU2.startDaemonTask=CCU2_VIC_VIStartDaemon diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h index 61d88949caef7136c74c3ec1dfb5f300b314a741..e29612d78dd9568757b7db80c6346a15c1851214 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h @@ -29,7 +29,7 @@ //# GCF Includes #include <GCF/PAL/GCF_MyPropertySet.h> #include <GCF/TM/GCF_Port.h> -#include <GCF/TM/GCF_TCPPort.h> +#include <GCF/TM/GCF_TimerPort.h> #include <GCF/TM/GCF_Task.h> #include <GCF/TM/GCF_Event.h> @@ -50,13 +50,16 @@ #include <OTDB/TreeMaintenance.h> #include <OTDB/OTDBnode.h> #include <APS/ParameterSet.h> +#include "ChildControl.h" +#include "LDState.h" // forward declaration namespace LOFAR { - namespace MCU { + namespace MainCU { -using GCF::TM::GCFTCPPort; +using GCF::TM::GCFTimerPort; +using GCF::TM::GCFPort; using GCF::TM::GCFEvent; using GCF::TM::GCFPortInterface; using GCF::TM::GCFTask; @@ -102,50 +105,6 @@ private: GCFMyPropertySetPtr itsPropertySet; #if 0 - typedef GCFTCPPort TRemotePort; - - typedef boost::shared_ptr<GCFTCPPort> TTCPPortPtr; - typedef boost::shared_ptr<TRemotePort> TRemotePortPtr; - typedef vector<TTCPPortPtr> TTCPPortVector; - typedef vector<TRemotePortPtr> TRemotePortVector; - typedef map<string,TRemotePortPtr> TStringRemotePortMap; - typedef map<string,TTCPPortPtr> TStringTCPportMap; - - bool _isServerPort (const GCFPortInterface& server, - const GCFPortInterface& port) const; - bool _isVISDclientPort (const GCFPortInterface& port, - string& visd) const; - bool _isVIclientPort (const GCFPortInterface& port) const; - string _getVInameFromPort (const GCFPortInterface& port) const; - string _getShareLocation () const; - - void createChildsSections(OTDB::TreeMaintenance& tm, - int32 treeID, - OTDB::nodeIDType topItem, - const string& nodeName, - boost::shared_ptr<ACC::APS::ParameterSet> ps); - - void _schedule (const string& VIrootID, - GCFPortInterface* port=0); - void _updateSchedule (const string& VIrootID, - GCFPortInterface* port=0); - void _cancelSchedule (const string& VIrootID, - GCFPortInterface* port=0); - - TStringRemotePortMap m_VISDclientPorts; // connected VI StartD clients - string m_VIparentPortName; - TRemotePort m_VIparentPort; // parent for VI's - - // the vector and map both contain the child ports. The vector is used - // to cache the port at the moment of the accept. However, at that moment, - // the parent does not yet know the ID of that child. The child sends its - // ID in the CONNECT event and when that message is received, the port and ID - // are stored in the TPortMap. The map is used in all communication with the - // childs. - TRemotePortVector m_VIclientPorts; // created VI's - TStringRemotePortMap m_connectedVIclientPorts; // maps node ID's to ports -#endif - // Administration of the ObservationControllers typedef struct { OTDB::treeIDType treeID; // tree in the OTDB @@ -156,17 +115,19 @@ private: // Map with all active ObservationControllers. map<GCFTCPPort*, ObsCntlr_t> itsObsCntlrMap; vector<GCFTCPPort*> itsObsCntlrPorts; +#endif // Ports for StartDaemon and ObservationControllers. - GCFTCPPort* itsSDclientPort; // connection to StartDaemon - GCFTCPPort* itsLDserverPort; // listener for ObsControllers + GCFTimerPort* itsDummyPort; // for timers + + // pointer to child control task + ChildControl* itsChildControl; // Second timer used for internal timing. uint32 itsSecondTimer; // 1 second hardbeat - uint32 itsSDretryTimer; // for reconnecting to SD // Scheduling settings - uint32 itsQueuePeriod; // period between qeueuing and start + uint32 itsQueuePeriod; // period between queueing and start uint32 itsClaimPeriod; // period between claiming and start // OTDB related variables. @@ -176,6 +137,6 @@ private: }; - };//MCU + };//MainCU };//LOFAR #endif diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in index 438f6f9039e915a79158e3b2d1db1ac5c6b1b39b..c5531d1e00011da09bbd1f0408e0963c1f008eca 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in @@ -1,29 +1,15 @@ # add your custom loggers and appenders here # -log4cplus.rootLogger=INFO, STDOUT +log4cplus.rootLogger=DEBUG, STDOUT -log4cplus.logger.TRC=PUTJE +log4cplus.logger.TRC=TRACE log4cplus.additivity.TRC=FALSE -log4cplus.logger.MAC=DEBUG, STDOUT, FILE -log4cplus.additivity.MAC=FALSE - -log4cplus.logger.TRC.MAC=TRACE, FILE -log4cplus.additivity.TRC.MAC=FALSE - -log4cplus.appender.PUTJE=log4cplus::NullAppender - log4cplus.appender.STDOUT=log4cplus::ConsoleAppender log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout log4cplus.appender.STDOUT.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S} %-5p %c{9} - %m [%.25l]%n log4cplus.appender.STDOUT.logToStdErr=true -#log4cplus.appender.STDOUT.Threshold=WARN -#log4cplus.appender.STDOUT.filters.1=log4cplus::spi::LogLevelRangeFilter -#log4cplus.appender.STDOUT.filters.1.LogLevelMin=INFO -#log4cplus.appender.STDOUT.filters.1.LogLevelMax=FATAL -#log4cplus.appender.STDOUT.filters.1.AcceptOnMatch=true -#log4cplus.appender.STDOUT.filters.2=log4cplus::spi::DenyAllFilter log4cplus.appender.FILE=log4cplus::RollingFileAppender log4cplus.appender.FILE.File=../log/MACScheduler.log diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h index 23c036e3733609adbe9f13ea2e941200f1917ca8..a88f2abbdb0dc71ea8072296fab6c210dc8cc635 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h +++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h @@ -28,8 +28,8 @@ namespace LOFAR { #define MS_TASKNAME "MACScheduler" -#define MS_PROPSET_NAME "MACScheduler" -#define MS_PROPSET_TYPE "TAplMacScheduler" +#define MS_PROPSET_NAME "SwCntrl" +#define MS_PROPSET_TYPE "MacScheduler" #define PVSSNAME_MS_QUEUEPERIOD "QueuePeriod" #define PVSSNAME_MS_CLAIMPERIOD "ClaimPeriod" @@ -38,9 +38,6 @@ namespace LOFAR { #define PVSSNAME_FSM_STATE "state" #define PVSSNAME_FSM_ERROR "error" -#define SN_STARTDAEMON "StartDaemon" -#define SN_STARTDAEMON_VERSION "V1" - }; // MCU }; // LOFAR diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc index 87f6cd0e21109d1809b0dfd847639747a5c9bdd4..1f1b70b6d7a82ca14d3de4bf2082aec684961423 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc @@ -1,6 +1,6 @@ -//# VirtualInstrumentStartDaemonMain.cc: Main entry for the VirtualInstrument start daemon +//# MACSchedulerMain.cc: Main entry for the MACScheduler controller. //# -//# Copyright (C) 2002-2005 +//# Copyright (C) 2006 //# ASTRON (Netherlands Foundation for Research in Astronomy) //# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl //# @@ -19,20 +19,27 @@ //# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //# //# $Id$ +//# #include <lofar_config.h> #include <Common/LofarLogger.h> #include "MACScheduler.h" +using namespace LOFAR::GCF::TM; +using namespace LOFAR::MainCU; + int main(int argc, char* argv[]) { - LOFAR::GCF::TM::GCFTask::init(argc, argv); - - LOFAR::MCU::MACScheduler ms; - ms.start(); // make initial transition - - LOFAR::GCF::TM::GCFTask::run(); - - return 0; + GCFTask::init(argc, argv); + + ChildControl* cc = ChildControl::instance(); + cc->start(); // make initial transition + + MACScheduler ms; + ms.start(); // make initial transition + + GCFTask::run(); + + return 0; } diff --git a/MAC/APL/MainCU/src/MACScheduler/Makefile.am b/MAC/APL/MainCU/src/MACScheduler/Makefile.am index 2b02b3957721c221a33145b83de9ef1a0a275834..68ec6941b0f59256f4344fcdfb16ad8f8db57a10 100644 --- a/MAC/APL/MainCU/src/MACScheduler/Makefile.am +++ b/MAC/APL/MainCU/src/MACScheduler/Makefile.am @@ -7,14 +7,17 @@ MACScheduler_CPPFLAGS = -DBOOST_DISABLE_THREADS \ MACScheduler_SOURCES = MACScheduler.cc \ MACSchedulerMain.cc \ - LogicalDeviceState.cc + ChildControl.cc \ + LDState.cc + MACScheduler_LDADD = -lpqxx $(LOFAR_DEPEND) MACScheduler_DEPENDENCIES = $(LOFAR_DEPEND) NOINSTHDRS = MACScheduler.h \ MACSchedulerDefines.h -INSTHDRS = LogicalDeviceState.h +INSTHDRS = ChildControl.h \ + LDState.h pkginclude_HEADERS = $(NOINSTHDRS) $(INSTHDRS) diff --git a/MAC/APL/_VIC/VirtualInstrument/configure.in b/MAC/APL/_VIC/VirtualInstrument/configure.in index d73efd3a25d0d8d9b59eedf2ef19e41d1b0f2d20..24282e97b4be6581cc9904e1b710a467e634f303 100644 --- a/MAC/APL/_VIC/VirtualInstrument/configure.in +++ b/MAC/APL/_VIC/VirtualInstrument/configure.in @@ -58,9 +58,9 @@ lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, MAC-GCF-6_0, 1, GCF/GCF_Defines.h,, lofar_INTERNAL(MAC/GCF/TM, gcftm, MAC-GCF-6_0, 1, GCF/TM/GCF_Task.h,,) lofar_INTERNAL(MAC/GCF/PAL, gcfpal, MAC-GCF-6_0, 1, GCF/PAL/GCF_PVSSInfo.h,,) lofar_INTERNAL(MAC/APL/APLCommon, aplcommon, MAC-APL-3_1, 1, APL/APLCommon/APL_Defines.h,,) -lofar_INTERNAL(MAC/APL/VIC/ArrayOperations, arrayoperations, MAC-APL-3_1, 1, APL/ArrayOperations/ArrayOperations.h,,) -lofar_INTERNAL(MAC/APL/VIC/ArrayReceptorGroup, arrayreceptorgroup, MAC-APL-3_1, 1, APL/ArrayReceptorGroup/ArrayReceptorGroup.h,,) -lofar_INTERNAL(MAC/APL/VIC/VirtualRoute, virtualroute, MAC-APL-4_0, 1, APL/VirtualRoute/VirtualRoute.h,,) +dnl lofar_INTERNAL(MAC/APL/VIC/ArrayOperations, arrayoperations, MAC-APL-3_1, 1, APL/ArrayOperations/ArrayOperations.h,,) +dnl lofar_INTERNAL(MAC/APL/VIC/ArrayReceptorGroup, arrayreceptorgroup, MAC-APL-3_1, 1, APL/ArrayReceptorGroup/ArrayReceptorGroup.h,,) +dnl lofar_INTERNAL(MAC/APL/VIC/VirtualRoute, virtualroute, MAC-APL-4_0, 1, APL/VirtualRoute/VirtualRoute.h,,) dnl dnl Output Makefiles diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.in b/MAC/APL/_VIC/VirtualInstrument/src/CCUStartDaemon.conf.in similarity index 74% rename from MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.in rename to MAC/APL/_VIC/VirtualInstrument/src/CCUStartDaemon.conf.in index e862ff7ebe2576164d3b391b613d9731904477c4..509899622096ce31fa928327fb54090dce33e440 100644 --- a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.in +++ b/MAC/APL/_VIC/VirtualInstrument/src/CCUStartDaemon.conf.in @@ -1,10 +1,9 @@ mac.ns.CCU1_VIC_VIStartDaemon.server.type=TCP mac.ns.CCU1_VIC_VIStartDaemon.server.host=lofar27 -#mac.ns.CCU1_VIC_VIStartDaemon.server.host=saturnus mac.ns.CCU1_VIC_VIStartDaemon.server.port=27010 + mac.ns.CCU2_VIC_VIStartDaemon.server.type=TCP mac.ns.CCU2_VIC_VIStartDaemon.server.host=lofar27 -#mac.ns.CCU2_VIC_VIStartDaemon.server.host=saturnus mac.ns.CCU2_VIC_VIStartDaemon.server.port=27010 #mac.ns.CEPLCU1_PAC_VBStartDaemon.server.type=TCP @@ -13,19 +12,16 @@ mac.ns.CCU2_VIC_VIStartDaemon.server.port=27010 mac.ns.PAC_VBStartDaemon.server.type=TCP mac.ns.PAC_VBStartDaemon.server.host=lofar30.astron.nl -#mac.ns.PAC_VBStartDaemon.server.host=sun mac.ns.PAC_VBStartDaemon.server.port=27010 -#mac.ns.Observation1.VI1.server.type=TCP -#mac.ns.Observation1.VI1.server.host=saturnus +mac.ns.Observation1.VI1.server.type=TCP +mac.ns.Observation1.VI1.server.host=saturnus ## when using BSE VB stub, the following port must be fixed: ##mac.ns.Observation1.VI1.server.port=27003 mac.ns.MAINTENANCE1.server.port=27004 -## mac.ns.MACScheduler.VIparent_server.type=TCP mac.ns.MACScheduler.VIparent_server.host=lofar27 -#mac.ns.MACScheduler.VIparent_server.host=saturnus # # mac.ns.MACScheduler.VIparent_server.remoteservice is dynamically configured @@ -33,4 +29,4 @@ mac.ns.MACScheduler.VIparent_server.host=lofar27 # mac.apl.ld.retryTimeout=600 mac.apl.ld.retryPeriod=1 -mac.apl.ld.shareLocation=/opt/lofar/MAC/parametersets/ +#mac.apl.ld.shareLocation=/opt/lofar/MAC/parametersets/ diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.log_prop.in b/MAC/APL/_VIC/VirtualInstrument/src/CCUStartDaemon.log_prop.in similarity index 100% rename from MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.log_prop.in rename to MAC/APL/_VIC/VirtualInstrument/src/CCUStartDaemon.log_prop.in diff --git a/MAC/APL/_VIC/VirtualInstrument/src/MaintenanceVI.cc b/MAC/APL/_VIC/VirtualInstrument/src/MaintenanceVI.cc index cc0d05d54682dd64828518eabb15c486dbcadd71..a04d1e3ab2c81be17bd4e6bb41ba938f3aff6a5e 100644 --- a/MAC/APL/_VIC/VirtualInstrument/src/MaintenanceVI.cc +++ b/MAC/APL/_VIC/VirtualInstrument/src/MaintenanceVI.cc @@ -66,7 +66,7 @@ MaintenanceVI::MaintenanceVI(const string& taskName, try { // put resources in a vector - m_resources = m_parameterSet.getStringVector(string("resources")); + m_resources = m_parameterSet->getStringVector(string("resources")); } catch(Exception& e) { diff --git a/MAC/APL/_VIC/VirtualInstrument/src/Makefile.am b/MAC/APL/_VIC/VirtualInstrument/src/Makefile.am index 1e8d44af755a29e524dfc2920240f7855c860cd5..62fe30dae6371347a386ec6a49faedfbd9bf4899 100644 --- a/MAC/APL/_VIC/VirtualInstrument/src/Makefile.am +++ b/MAC/APL/_VIC/VirtualInstrument/src/Makefile.am @@ -1,29 +1,35 @@ -bin_PROGRAMS = VirtualInstrument +bin_PROGRAMS = CCUStartDaemon MaintenanceVI VirtualInstrument ObservationVI -VirtualInstrument_CPPFLAGS = \ - -DBOOST_DISABLE_THREADS \ - -Wno-deprecated \ - -fmessage-length=0 \ - -fdiagnostics-show-location=once -# -DUSE_PVSSPORT +#VirtualInstrument_CPPFLAGS = \ +# -DBOOST_DISABLE_THREADS \ +# -Wno-deprecated \ +# -fmessage-length=0 \ +# -fdiagnostics-show-location=once +## -DUSE_PVSSPORT -VirtualInstrument_LDADD = $(LOFAR_DEPEND) -VirtualInstrument_DEPENDENCIES = $(LOFAR_DEPEND) +CCUStartDaemon_SOURCES = CCUStartDaemonMain.cc +CCUStartDaemon_DEPENDENCIES = $(LOFAR_DEPEND) +CCUStartDaemon_LDADD = + +MaintenanceVI_SOURCES = MaintenanceVI.cc MaintenanceVIMain.cc +MaintenanceVI_DEPENDENCIES = $(LOFAR_DEPEND) +MaintenanceVI_LDADD = -VirtualInstrument_SOURCES = \ - $(DOCHDRS) \ - VirtualInstrument.cc \ - MaintenanceVI.cc \ - ObservationVI.cc \ - VirtualInstrumentStartDaemonMain.cc +VirtualInstrument_SOURCES = VirtualInstrument.cc VirtualInstrumentMain.cc +VirtualInstrument_DEPENDENCIES = $(LOFAR_DEPEND) +VirtualInstrument_LDADD = -NOINSTHDRS = +ObservationVI_SOURCES = ObservationVI.cc ObservationVIMain.cc +ObservationVI_DEPENDENCIES = $(LOFAR_DEPEND) +ObservationVI_LDADD = -INSTHDRS = \ +NOINSTHDRS = \ VirtualInstrument.h \ MaintenanceVI.h \ ObservationVI.h +INSTHDRS = + pkginclude_HEADERS = $(NOINSTHDRS) $(INSTHDRS) DOCHDRS = $(pkginclude_HEADERS) $(BUILT_SOURCES) @@ -39,8 +45,8 @@ configfilesdir=$(bindir) configfiles_DATA = sysconf_DATA = \ - VirtualInstrument.conf \ - VirtualInstrument.log_prop + CCUStartDaemon.conf \ + CCUStartDaemon.log_prop %.log_prop: %.log_prop.in cp $< $@ diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc index ba23875fb2529e89e23ff6aa723ecb1046db4256..b8d8cc14717784118ccd910d6b622f34a446d570 100644 --- a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc +++ b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc @@ -354,9 +354,9 @@ bool VirtualInstrument::_checkQualityRequirements(const TLogicalDeviceState& req bool vbQualityOk(false); bool vtQualityOk(false); bool vrQualityOk(false); - double requiredVBavailability = m_parameterSet.getDouble(string("requiredVBavailability")); - double requiredVRavailability = m_parameterSet.getDouble(string("requiredVRavailability")); - double requiredVTavailability = m_parameterSet.getDouble(string("requiredVTavailability")); + double requiredVBavailability = m_parameterSet->getDouble(string("requiredVBavailability")); + double requiredVRavailability = m_parameterSet->getDouble(string("requiredVRavailability")); + double requiredVTavailability = m_parameterSet->getDouble(string("requiredVTavailability")); // ALL virtual backend childs must be claimed vbQualityOk = _childsInState(requiredVBavailability, LDTYPE_VIRTUALBACKEND, requiredState); diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.local.in b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.local.in deleted file mode 100644 index 6d1092d908700b5bfc108a0bfaadd6d346163fa9..0000000000000000000000000000000000000000 --- a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.conf.local.in +++ /dev/null @@ -1,36 +0,0 @@ -mac.ns.CCU1_VIC_VIStartDaemon.server.type=TCP -#mac.ns.CCU1_VIC_VIStartDaemon.server.host=lofar27 -mac.ns.CCU1_VIC_VIStartDaemon.server.host=saturnus -mac.ns.CCU1_VIC_VIStartDaemon.server.port=27010 -mac.ns.CCU2_VIC_VIStartDaemon.server.type=TCP -#mac.ns.CCU2_VIC_VIStartDaemon.server.host=lofar27 -mac.ns.CCU2_VIC_VIStartDaemon.server.host=saturnus -mac.ns.CCU2_VIC_VIStartDaemon.server.port=27010 - -#mac.ns.CEPLCU1_PAC_VBStartDaemon.server.type=TCP -#mac.ns.CEPLCU1_PAC_VBStartDaemon.server.host=sun -#mac.ns.CEPLCU1_PAC_VBStartDaemon.server.port=27010 - -mac.ns.PAC_VBStartDaemon.server.type=TCP -#mac.ns.PAC_VBStartDaemon.server.host=lofar30.astron.nl -mac.ns.PAC_VBStartDaemon.server.host=sun -mac.ns.PAC_VBStartDaemon.server.port=27010 - -#mac.ns.Observation1.VI1.server.type=TCP -#mac.ns.Observation1.VI1.server.host=saturnus -## when using BSE VB stub, the following port must be fixed: -##mac.ns.Observation1.VI1.server.port=27003 -mac.ns.MAINTENANCE1.server.port=27004 -## - -mac.ns.MACScheduler.VIparent_server.type=TCP -#mac.ns.MACScheduler.VIparent_server.host=lofar27 -mac.ns.MACScheduler.VIparent_server.host=saturnus - -# -# mac.ns.MACScheduler.VIparent_server.remoteservice is dynamically configured -# because it depends on the VI name -# -mac.apl.ld.retryTimeout=600 -mac.apl.ld.retryPeriod=1 -mac.apl.ld.shareLocation=/opt/lofar/MAC/parametersets/ diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrumentStartDaemonMain.cc b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrumentStartDaemonMain.cc deleted file mode 100644 index ab51333beb3d2b66f7666fc97b1fcc2c354a59e2..0000000000000000000000000000000000000000 --- a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrumentStartDaemonMain.cc +++ /dev/null @@ -1,72 +0,0 @@ -//# VirtualInstrumentStartDaemonMain.cc: Main entry for the VirtualInstrument start daemon -//# -//# 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$ -#undef PACKAGE -#undef VERSION -#include <lofar_config.h> -#include <Common/LofarLogger.h> - -#include <boost/shared_ptr.hpp> -#include <APL/APLCommon/StartDaemon.h> -#include "VirtualInstrument.h" -#include "MaintenanceVI.h" -#include "ObservationVI.h" -#include <APL/ArrayReceptorGroup/ArrayReceptorGroup.h> -#include <APL/ArrayOperations/ArrayOperations.h> -#include <APL/VirtualRoute/VirtualRoute.h> -#include <APL/APLCommon/LogicalDeviceFactory.h> -#include <APL/APLCommon/SharedLogicalDeviceFactory.h> - -using namespace LOFAR; -using namespace LOFAR::GCF::Common; -using namespace LOFAR::GCF::TM; -using namespace LOFAR::GCF::PAL; -using namespace LOFAR::APLCommon; -using namespace LOFAR::AVI; // A)pplication layer V)irtual I)nstrument -using namespace LOFAR::AAO; // A)pplication layer A)rray O)perations -using namespace LOFAR::AAR; // A)pplication layer A)rray R)eceptor group -using namespace LOFAR::AVR; // A)pplication layer V)irtual R)oute - -int main(int argc, char* argv[]) -{ - GCFTask::init(argc, argv); - - boost::shared_ptr<LogicalDeviceFactory<VirtualInstrument> > viFactory(new LogicalDeviceFactory<VirtualInstrument>); - boost::shared_ptr<SharedLogicalDeviceFactory<ArrayReceptorGroup> > argFactory(new SharedLogicalDeviceFactory<ArrayReceptorGroup>); - boost::shared_ptr<SharedLogicalDeviceFactory<ArrayOperations> > aoFactory(new SharedLogicalDeviceFactory<ArrayOperations>); - boost::shared_ptr<LogicalDeviceFactory<VirtualRoute> > vrFactory(new LogicalDeviceFactory<VirtualRoute>); - boost::shared_ptr<LogicalDeviceFactory<MaintenanceVI> > mviFactory(new LogicalDeviceFactory<MaintenanceVI>); - boost::shared_ptr<LogicalDeviceFactory<ObservationVI> > oviFactory(new LogicalDeviceFactory<ObservationVI>); - - StartDaemon sd(string("VIC_VIStartDaemon")); - sd.registerFactory(LDTYPE_VIRTUALINSTRUMENT,viFactory); - sd.registerFactory(LDTYPE_ARRAYRECEPTORGROUP,argFactory); - sd.registerFactory(LDTYPE_ARRAYOPERATIONS,aoFactory); - sd.registerFactory(LDTYPE_VIRTUALROUTE,vrFactory); - sd.registerFactory(LDTYPE_MAINTENANCEVI,mviFactory); - sd.registerFactory(LDTYPE_OBSERVATION,oviFactory); - sd.start(); // make initial transition - - GCFTask::run(); - - return 0; -} - diff --git a/MAC/GCF/GCFCommon/GCFCommon.spec.in b/MAC/GCF/GCFCommon/GCFCommon.spec.in index f585660834a8fdf5d3f9d54c28926bfe3255e78d..8fe3d22737e60bd26ece7ea9c05324b1b6974526 100644 --- a/MAC/GCF/GCFCommon/GCFCommon.spec.in +++ b/MAC/GCF/GCFCommon/GCFCommon.spec.in @@ -29,6 +29,7 @@ URL: http://www.astron.nl Prefix: %{prefix} BuildArchitectures: i386 # Target platforms, i.e., i586 Requires: Common >= 2.2 +Requires: APS >= 2.0 Packager: %{packager} Distribution: The LOFAR project Vendor: ASTRON diff --git a/MAC/GCF/GCFCommon/configure.in b/MAC/GCF/GCFCommon/configure.in index 14b48495f5fac6ad87b8267a0c7719d719fa7bd7..f9681e68914467202c2396d987708168395cbe36 100644 --- a/MAC/GCF/GCFCommon/configure.in +++ b/MAC/GCF/GCFCommon/configure.in @@ -39,6 +39,7 @@ dnl Check for LOFAR specific things dnl lofar_GENERAL lofar_INTERNAL(LCS/Common, Common, LCS-Common-2_3, 1, Common/LofarTypes.h,,) +lofar_INTERNAL(LCS/ACC/APS, APS, , 1, APS/ParameterSet.h,,) dnl dnl Output Makefiles diff --git a/MAC/GCF/GCFCommon/include/GCF/GCF_ServiceInfo.h b/MAC/GCF/GCFCommon/include/GCF/GCF_ServiceInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..1719a08d34a21c344527891d48aef50610943dbf --- /dev/null +++ b/MAC/GCF/GCFCommon/include/GCF/GCF_ServiceInfo.h @@ -0,0 +1,80 @@ +//# GCF_ServiceInfo.h: Contains all information about the MAC services. +//# +//# 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 GCFCOMMON_SERVICEINFO_H +#define GCFCOMMON_SERVICEINFO_H + +// \file GCF_ServiceInfo.h +// Contains all information about the MAC services. + +//# Never #include <config.h> or #include <lofar_config.h> in a header file! +//# Includes + +// Avoid 'using namespace' in headerfiles + +namespace LOFAR { + namespace GCFCommon { + +// \addtogroup gcfcommon +// @{ + +// The only well-known port of whole MAC. +#define MAC_SERVICEBROKER_PORT 24000 + +// Define names for the services +#define MAC_SVCMASK_RSPDRIVER "RSPDriver%s:acceptor_v3" +#define MAC_SVCMASK_CALSERVER "CalServer%s:acceptor_v2" +#define MAC_SVCMASK_BEAMSERVER "BeamServer%s:acceptor_v2" +#define MAC_SVCMASK_PROPERTYAGENT "GCF-PA%s:provider" + +// Define names for the daemons +#define MAC_SVCMASK_SERVICEBROKER "ServiceBroker%s:v1.0" +#define MAC_SVCMASK_STARTDAEMON "StartDaemon%s:v1.0" + +// Define names for all controllers +#define MAC_SVCMASK_SCHEDULERCTRL "MACScheduler%s:v1.0" +#define MAC_SVCMASK_OBSERVATIONCTRL "Observation%s:v1.0" +#define MAC_SVCMASK_BEAMDIRECTIONCTRL "BeamDirection%s:v1.0" +#define MAC_SVCMASK_GROUPCTRL "RingControl%s:v1.0" +#define MAC_SVCMASK_STATIONCTRL "StationControl%s:v1.0" +#define MAC_SVCMASK_DIGITALBOARDCTRL "DigitalBoardCtrl%s:v1.0" +#define MAC_SVCMASK_BEAMCTRL "BeamCtrl%s:v1.0" +#define MAC_SVCMASK_CALIBRATIONCTRL "CalibrationCtrl%s:v1.0" +#define MAC_SVCMASK_STATIONINFRACTRL "StationInfraCtrl%s:v1.0" + + + + + + + + + + + + + +// @} + } // namespace GCFCommon +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/GCFCommon/include/GCF/Makefile.am b/MAC/GCF/GCFCommon/include/GCF/Makefile.am index 95a66379bee3b2456511d291323ee035451b9524..d56d5bb41382942485c66c079f54c5e95cf1b82f 100644 --- a/MAC/GCF/GCFCommon/include/GCF/Makefile.am +++ b/MAC/GCF/GCFCommon/include/GCF/Makefile.am @@ -14,7 +14,7 @@ pkginclude_HEADERS = \ CmdLine.h \ Utils.h \ GCF_Defines.h \ - ParameterSet.h \ + GCF_ServiceInfo.h \ Thread.h \ Mutex.h diff --git a/MAC/GCF/GCFCommon/include/GCF/ParameterSet.h b/MAC/GCF/GCFCommon/include/GCF/ParameterSet.h deleted file mode 100644 index 5e86267528523a19d4f00e30e6006072dee46e09..0000000000000000000000000000000000000000 --- a/MAC/GCF/GCFCommon/include/GCF/ParameterSet.h +++ /dev/null @@ -1,117 +0,0 @@ -//# ParameterSet.h: Implements a map of Key-Value pairs. -//# -//# 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 -//# -//# This class implements a container of key-value pairs. The KV pairs can -//# be read from a file or be merged with the values in another file. -//# The class also support the creation of subsets. -//# -//# $Id$ - -#ifndef PARAMETERSET_H -#define PARAMETERSET_H - -//# Includes -#include <Common/lofar_string.h> -#include <Common/lofar_map.h> -#include <Common/LofarLogger.h> - -namespace LOFAR -{ - namespace GCF - { - -//# Description of class. -// The ParameterSet class is an implementation of a map <string, string>. This -// means that the Value is stored as a string which allows easy merging and -// splitting of ParameterSets because no conversions have to be done. -// A couple of getXxx routines convert the strings to the desired type. -// -class ParameterSet : public map <string, string> -{ -public: - typedef map<string, string>::iterator iterator; - typedef map<string, string>::const_iterator const_iterator; - - static ParameterSet* instance(); - - // Default constructable; - ParameterSet(); - ~ParameterSet(); - - // The ParameterSet may be construction by reading a parameter file. - explicit ParameterSet(const string& theFilename, const string& searchPath = ""); - - // Copying is allowed. - ParameterSet(const ParameterSet& that); - ParameterSet& operator=(const ParameterSet& that); - - void setSearchPath(const string& searchPath); - string getSearchPath() const; - // Adds the Key-Values pair in the given file to the current ParameterSet. - void adoptFile (const string& theFilename); - void adoptBuffer(const string& theBuffer); - - // Writes the Key-Values pair from the current ParameterSet to the file. - void writeFile (const string& theFilename) const; - void writeBuffer (const string& theBuffer) const; - - // Creates a subset from the current ParameterSet containing all the - // parameters that start with the given baseKey. The baseKey is cut off - // from the Keynames in the created subset. - ParameterSet makeSubset(const string& baseKey) const; - - // Checks if the given Key is defined in the ParameterSet. - bool isDefined (const string& searchKey) const; - - int getInt (const string& theKey) const; - double getDouble(const string& theKey) const; - float getFloat(const string& theKey) const; - string getString(const string& theKey) const; - - friend std::ostream& operator<<(std::ostream& os, const ParameterSet &thePS); - -private: - void readFile (const string& theFile, const bool merge); - void readBuffer (const string& theFile, const bool merge); - void addStream (istream& inputStream, const bool merge); - - string _searchPath; - static ParameterSet* _pInstance; -}; - -inline void ParameterSet::setSearchPath(const string& searchPath) -{ - _searchPath = searchPath; -} - -inline string ParameterSet::getSearchPath() const -{ - return _searchPath; -} - -inline bool ParameterSet::isDefined (const string& searchKey) const -{ - return (find(searchKey) != end()); -} - } // namespace GCF -} // namespace LOFAR -using namespace LOFAR::GCF; - -#endif diff --git a/MAC/GCF/GCFCommon/include/GCF/Utils.h b/MAC/GCF/GCFCommon/include/GCF/Utils.h index 67c3903f6bb12cf32bf147304e940860e49298dc..3cfd0628975adb15116742f51352afc3926ea241 100644 --- a/MAC/GCF/GCFCommon/include/GCF/Utils.h +++ b/MAC/GCF/GCFCommon/include/GCF/Utils.h @@ -12,24 +12,17 @@ namespace LOFAR namespace Common { -class Utils -{ - public: - - Utils(); - ~Utils(); - - static void convListToString(std::string& listString, - const std::list<std::string>& stringList); - static void convStringToList(std::list<std::string>& stringList, - const std::string& listString); - static void convSetToString(std::string& setString, - const std::set<std::string>& stringSet); - static void convStringToSet(std::set<std::string>& stringSet, - const std::string& setString); - static bool isValidPropName(const char* propName); - static bool isValidScope(const char* scopeName); -}; +void convListToString(std::string& listString, + const std::list<std::string>& stringList); +void convStringToList(std::list<std::string>& stringList, + const std::string& listString); +void convSetToString(std::string& setString, + const std::set<std::string>& stringSet); +void convStringToSet(std::set<std::string>& stringSet, + const std::string& setString); +bool isValidPropName(const char* propName); +bool isValidScope (const char* scopeName); +string myHostname (bool giveFullName = false); } // namespace Common } // namespace GCF diff --git a/MAC/GCF/GCFCommon/src/CmdLine.cc b/MAC/GCF/GCFCommon/src/CmdLine.cc index 0981a7395962d2069853b3e23ec3301115dbfd4c..4f4e548980dd73e52436377dc8862a1417592429 100644 --- a/MAC/GCF/GCFCommon/src/CmdLine.cc +++ b/MAC/GCF/GCFCommon/src/CmdLine.cc @@ -29,8 +29,8 @@ See SACmds.h for more info. ------------------------------------------------------*/ -// if you're using MFC, you'll need to un-comment this line -// #include "stdafx.h" +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> #include <GCF/CmdLine.h> #include <ctype.h> diff --git a/MAC/GCF/GCFCommon/src/GCF_PValue.cc b/MAC/GCF/GCFCommon/src/GCF_PValue.cc index 26ead11e8e4876dac5e46bb6b301e03be44a4d17..cce0387b965db1c7a5a7c5ef347b3d3ccac58517 100644 --- a/MAC/GCF/GCFCommon/src/GCF_PValue.cc +++ b/MAC/GCF/GCFCommon/src/GCF_PValue.cc @@ -31,7 +31,7 @@ #include <GCF/GCF_PVUnsigned.h> #include <GCF/GCF_PVDynArr.h> #include <GCF/GCF_PVBlob.h> -#include "GCO_Defines.h" +#include <GCF/GCF_Defines.h> namespace LOFAR { diff --git a/MAC/GCF/GCFCommon/src/GCO_Defines.h b/MAC/GCF/GCFCommon/src/GCO_Defines.h deleted file mode 100644 index e425c477423f17bdd185ad5fb8d8ab38509e52ba..0000000000000000000000000000000000000000 --- a/MAC/GCF/GCFCommon/src/GCO_Defines.h +++ /dev/null @@ -1,39 +0,0 @@ -//# GCO_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 UCO -//# -//# $Id$ - -#ifndef GCO_DEFINES_H -#define GCO_DEFINES_H - -#include <GCF/GCF_Defines.h> - -namespace LOFAR -{ - namespace GCF - { - namespace Common - { - - } // namespace Common - } // namespace GCF -} // namespace LOFAR - -#endif diff --git a/MAC/GCF/GCFCommon/src/Makefile.am b/MAC/GCF/GCFCommon/src/Makefile.am index fdbb4d98561914587c56d969a2fa7c79952c8bad..06315932cc5513e749532c317653aae5f6e5ba81 100644 --- a/MAC/GCF/GCFCommon/src/Makefile.am +++ b/MAC/GCF/GCFCommon/src/Makefile.am @@ -16,7 +16,6 @@ libgcfcommon_la_SOURCES= $(DOCHDRS) \ GCF_PVUnsigned.cc \ GCF_PVDynArr.cc \ GCF_PVBlob.cc \ - ParameterSet.cc \ Thread.cc include $(top_srcdir)/Makefile.common diff --git a/MAC/GCF/GCFCommon/src/ParameterSet.cc b/MAC/GCF/GCFCommon/src/ParameterSet.cc deleted file mode 100644 index ee0cd31a4795fca913197454249bb82fb0d66b50..0000000000000000000000000000000000000000 --- a/MAC/GCF/GCFCommon/src/ParameterSet.cc +++ /dev/null @@ -1,351 +0,0 @@ -//# ParameterSet.cc: Implements a map of Key-Value pairs. -//# -//# 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$ - -#include <lofar_config.h> - -#include <GCF/ParameterSet.h> -#include <Common/lofar_fstream.h> -#include <Common/lofar_sstream.h> -using std::istringstream; -using std::ifstream; - -namespace LOFAR -{ - namespace GCF - { - -ParameterSet* ParameterSet::_pInstance = 0; - -ParameterSet* ParameterSet::instance() -{ - if (_pInstance == 0) - { - _pInstance = new ParameterSet(); - } - return _pInstance; -} - -//#-------------------------- creation and destroy --------------------------- -//# -//# Default constructor -//# -ParameterSet::ParameterSet() -{} - -//# -//# Construction by reading a parameter file. -//# -ParameterSet::ParameterSet(const string& theFilename, const string& searchPath) : - _searchPath(searchPath) -{ - readFile(theFilename, false); -} - -//# -//# Copying is allowed. -//# -ParameterSet::ParameterSet(const ParameterSet& that) - : map<string, string> (that) -{} - -//# -//# operator= copying -//# -ParameterSet& ParameterSet::operator=(const ParameterSet& that) -{ - if (this != &that) { - map<string, string>::operator= (that); - } - return (*this); -} - -//# -//# Destructor -//# -ParameterSet::~ParameterSet() -{} - -//# -//# operator<< -//# -std::ostream& operator<< (std::ostream& os, const ParameterSet &thePS) -{ - map<string,string>::const_iterator iter = thePS.begin(); - - while (iter != thePS.end()) { - os << "[" << iter->first << "],[" << iter->second << "]" << endl; - iter++; - } - - return os; -} - -//#-------------------------- merge and split -------------------------------- -//# -//# makeSubset(baseKey) -//# -// Creates a Subset from the current ParameterSet containing all the parameters -// that start with the given baseKey. The baseKey is cut off from the Keynames -// in the created subset. -// -ParameterSet ParameterSet::makeSubset(const string& baseKey) const -{ - const_iterator scanner = begin(); - int baseKeyLen = baseKey.length(); - ParameterSet subSet; - - //# Scan through whole ParameterSet - while (scanner != end()) { - //# starts with basekey? - if (!strncmp(baseKey.c_str(), scanner->first.c_str(), baseKeyLen)) { - //# cut off and copy to subset - subSet[scanner->first.c_str()+baseKeyLen] = scanner->second; - } - scanner++; - } - - return (subSet); -} - -//# -//# adoptFile -//# -// Adds the parameters from the file to the current ParameterSet. -// -void ParameterSet::adoptFile(const string& theFilename) -{ - readFile(theFilename, true); -} - -//# -//# adoptBuffer -//# -// Adds the parameters from the string to the current ParameterSet. -// -void ParameterSet::adoptBuffer(const string& theBuffer) -{ - readBuffer(theBuffer, true); -} - -//# -//# readFile -//# (private) -//# -// Disentangles the file and adds the Key-Values pair to the current ParameterSet. -// -void ParameterSet::readFile(const string& theFilename, - const bool merge) -{ - ifstream paramFile; - - string fullFileName(theFilename); - if (theFilename.find('/') == string::npos) - { - fullFileName = _searchPath; - if (_searchPath.length() > 0 && _searchPath.rfind('/') != (_searchPath.length() - 1)) - { - fullFileName += '/'; - } - fullFileName += theFilename; - } - //# Try to pen the file - paramFile.open(fullFileName.c_str(), ifstream::in); - if (!paramFile) { - THROW (Exception, formatString("Unable to open file %s", fullFileName.c_str())); - } - - addStream(paramFile, merge); - - paramFile.close(); -} - -//# -//# readBuffer -//# (private) -//# -// Disentangles the file and adds the Key-Values pair to the current ParameterSet. -// -void ParameterSet::readBuffer(const string& theBuffer, - const bool merge) -{ - istringstream iss(theBuffer, istringstream::in); - - addStream(iss, merge); - -} - -//# -//# addStream -//# (private) -//# -// Disentangles the stream and adds the Key-Values pair to the current ParameterSet. -// -void ParameterSet::addStream(istream& inputStream, bool merge) -{ - char paramLine[2*1024]; - char* separator; - //# Read the file line by line and convert it to Key Value pairs. - while (inputStream.getline (paramLine, 2*1024)) { - LOG_TRACE_VAR(formatString("data:>%s<", paramLine)); - - if (!paramLine[0] || paramLine[0] == '#') { //# skip empty lines - continue; //# and comment lines - } - - //# TODO: allow multiline parametervalues - //# line must have an equal-character ofcourse. - separator = strstr(paramLine, "="); - if (!separator) { - THROW (Exception, formatString("No '=' found in %s", paramLine)); - } - *separator= '\0'; //# terminate key string - ++separator; //# place on 1st char of value-part - - //# check for quoted strings, cutoff quotes - int valueLen = strlen(separator)-1; - if ((valueLen > 0) && (*separator == '"' || *separator == '\'') && - (*separator == separator[valueLen])) { - separator[valueLen] = '\0'; - ++separator; - } - - LOG_TRACE_VAR(formatString("pair:[%s][%s]", paramLine, separator)); - - //# remove any existed value and insert this value - if ((erase(paramLine) > 0) && !merge) { - LOG_WARN ( - formatString("Key %s is defined twice. Ignoring first value.", - paramLine)); - } - pair< map<string, string>::iterator, bool> result; - result = insert(std::make_pair(paramLine, separator)); //# add to map - if (!result.second) { - THROW (Exception, formatString("Key %s double defined?", paramLine)); - } - } -} - -//#-------------------------- retrieve functions ----------------------------- -//# -//# getInt(key) -//# -int ParameterSet::getInt(const string& theKey) const -{ - int theInt; - const_iterator iter = find (theKey); - - if (iter == end()) { - THROW (Exception, formatString("Key %s unknown", theKey.c_str())); - } - if (sscanf (iter->second.c_str(), "%d", &theInt) != 1) { - THROW (Exception, formatString("%s is not an integer value", iter->second.c_str())); - } - return (theInt); -} - -//# -//# getDouble(key) -//# -double ParameterSet::getDouble(const string& theKey) const - -{ - double theDouble; - const_iterator iter = find (theKey); - - if (iter == end()) { - THROW (Exception, formatString("Key %s unknown", theKey.c_str())); - } - if (sscanf (iter->second.c_str(), "%lg", &theDouble) != 1) { - THROW (Exception, formatString("%s is not a double value", iter->second.c_str())); - } - return (theDouble); -} - -//# -//# getFloat(key) -//# -float ParameterSet::getFloat(const string& theKey) const - -{ - float theFloat; - const_iterator iter = find (theKey); - - if (iter == end()) { - THROW (Exception, formatString("Key %s unknown", theKey.c_str())); - } - if (sscanf (iter->second.c_str(), "%e", &theFloat) != 1) { - THROW (Exception, formatString("%s is not a float value", iter->second.c_str())); - } - return (theFloat); -} - -//# -//# getString(key) -//# -string ParameterSet::getString(const string& theKey) const -{ - const_iterator iter = find (theKey); - - if (iter == end()) { - THROW (Exception, formatString("Key %s unknown", theKey.c_str())); - } - return (iter->second); -} - -//#---------------------------- save functions ------------------------------- -//# -//# writeFile -//# -// Writes the Key-Values pair from the current ParameterSet to the given file -// thereby overwritting any file contents. -// -void ParameterSet::writeFile(const string& theFilename) const -{ - ofstream paramFile; - - //# Try to pen the file - paramFile.open(theFilename.c_str(), ofstream::out | ofstream::trunc); - if (!paramFile) { - THROW (Exception, formatString("Unable to open file %s", theFilename.c_str())); - } - - //# Write all the pairs to the file - const_iterator curPair = begin(); - while (curPair != end()) { - //# Key can always be written. - paramFile << curPair->first << "="; - - //* value may begin or end in a space: use quotes - if (*(curPair->second.begin()) == ' ' || *(curPair->second.rbegin()) == ' ') { - paramFile << "\"" << curPair->second << "\"" << endl; - } - else { - paramFile << curPair->second << endl; - } - - curPair++; - } - - paramFile.close(); -} - } // namespace GCF -} // namespace LOFAR diff --git a/MAC/GCF/GCFCommon/src/Utils.cc b/MAC/GCF/GCFCommon/src/Utils.cc index 0b70205d8edf44c19512c5ae27f818f37e60735c..e75c75ec9a8c1118d1757741285428bb6f695a3b 100644 --- a/MAC/GCF/GCFCommon/src/Utils.cc +++ b/MAC/GCF/GCFCommon/src/Utils.cc @@ -2,6 +2,7 @@ #include <GCF/Utils.h> #include <stdio.h> +#include <unistd.h> #include <GCF/GCF_Defines.h> using std::set; @@ -13,24 +14,19 @@ namespace LOFAR namespace Common { -Utils::Utils() -{} -Utils::~Utils() -{} -void Utils::convListToString(string& listString, +void convListToString(string& listString, const list<string>& stringList) { listString.clear(); for (list<string>::const_iterator iter = stringList.begin(); - iter != stringList.end(); ++iter) - { + iter != stringList.end(); ++iter) { listString += *iter; listString += '|'; } } -void Utils::convStringToList(list<string>& stringList, +void convStringToList(list<string>& stringList, const string& listString) { unsigned int dataLength = listString.length(); @@ -38,12 +34,10 @@ void Utils::convStringToList(list<string>& stringList, memcpy(data, listString.c_str(), dataLength); data[dataLength] = 0; stringList.clear(); - if (dataLength > 0) - { + if (dataLength > 0) { string stringListItem; char* pStringListItem = strtok(data, "|"); - while (pStringListItem && dataLength > 0) - { + while (pStringListItem && dataLength > 0) { stringListItem = pStringListItem; pStringListItem = strtok(NULL, "|"); dataLength -= (stringListItem.size() + 1); @@ -52,19 +46,18 @@ void Utils::convStringToList(list<string>& stringList, } } -void Utils::convSetToString(string& setString, +void convSetToString(string& setString, const set<string>& stringSet) { setString.clear(); for (set<string>::const_iterator iter = stringSet.begin(); - iter != stringSet.end(); ++iter) - { + iter != stringSet.end(); ++iter) { setString += *iter; setString += '|'; } } -void Utils::convStringToSet(set<string>& stringSet, +void convStringToSet(set<string>& stringSet, const string& setString) { unsigned int dataLength = setString.length(); @@ -72,12 +65,10 @@ void Utils::convStringToSet(set<string>& stringSet, memcpy(data, setString.c_str(), dataLength); data[dataLength] = 0; stringSet.clear(); - if (dataLength > 0) - { + if (dataLength > 0) { string stringSetItem; char* pStringSetItem = strtok(data, "|"); - while (pStringSetItem && dataLength > 0) - { + while (pStringSetItem && dataLength > 0) { stringSetItem = pStringSetItem; pStringSetItem = strtok(NULL, "|"); dataLength -= (stringSetItem.size() + 1); @@ -86,48 +77,38 @@ void Utils::convStringToSet(set<string>& stringSet, } } -bool Utils::isValidPropName(const char* propName) +bool isValidPropName(const char* propName) { bool valid(true); ASSERT(propName); char doubleSep[] = {GCF_PROP_NAME_SEP, GCF_PROP_NAME_SEP, 0}; unsigned int length = strlen(propName); - if (propName[0] == GCF_PROP_NAME_SEP || propName[length - 1] == GCF_PROP_NAME_SEP ) - { + if (propName[0] == GCF_PROP_NAME_SEP || propName[length - 1] == GCF_PROP_NAME_SEP ) { valid = false; } - else if (strstr(propName, doubleSep) != 0) - { + else if (strstr(propName, doubleSep) != 0) { valid = false; } - else - { + else { char refInd[] = "__"; char* refIndPos = strstr(propName, refInd); - if (refIndPos != 0) - { - if (refIndPos > propName) - { - if (*(refIndPos - 1) != GCF_PROP_NAME_SEP) - { + if (refIndPos != 0) { + if (refIndPos > propName) { + if (*(refIndPos - 1) != GCF_PROP_NAME_SEP) { // ref indication may only found at begin or after a GCF_PROP_NAME_SEP valid = false; } } - if (valid && strchr(refIndPos, GCF_PROP_NAME_SEP) > 0) - { + if (valid && strchr(refIndPos, GCF_PROP_NAME_SEP) > 0) { // ref indication may not used in struct name valid = false; } } - for (unsigned short i = 0; valid && i < length; i++) - { - if (refIndPos > 0 && ((propName + i) == refIndPos)) - { + for (unsigned short i = 0; valid && i < length; i++) { + if (refIndPos > 0 && ((propName + i) == refIndPos)) { i += 2; // skip the ref indicator } - if (!isalnum(propName[i]) && propName[i] != GCF_PROP_NAME_SEP) - { + if (!isalnum(propName[i]) && propName[i] != GCF_PROP_NAME_SEP) { valid = false; } } @@ -135,38 +116,52 @@ bool Utils::isValidPropName(const char* propName) return valid; } -bool Utils::isValidScope(const char* scopeName) +bool isValidScope(const char* scopeName) { bool valid(true); ASSERT(scopeName); char doubleSep[] = {GCF_SCOPE_NAME_SEP, GCF_SCOPE_NAME_SEP, 0}; unsigned int length = strlen(scopeName); char* sysNameSep = strchr(scopeName, ':'); - if (sysNameSep > 0) - { + if (sysNameSep > 0) { length -= (sysNameSep + 1 - scopeName); scopeName = sysNameSep + 1; } - if (scopeName[0] == GCF_SCOPE_NAME_SEP || scopeName[length - 1] == GCF_SCOPE_NAME_SEP ) - { + if (scopeName[0] == GCF_SCOPE_NAME_SEP || scopeName[length - 1] == GCF_SCOPE_NAME_SEP ) { valid = false; } - else if (strstr(scopeName, doubleSep) != 0) - { + else if (strstr(scopeName, doubleSep) != 0) { valid = false; } - else - { - for(unsigned short i = 0; valid && i < length; i++) - { - if (!isalnum(scopeName[i]) && scopeName[i] != GCF_SCOPE_NAME_SEP) - { + else { + for(unsigned short i = 0; valid && i < length; i++) { + if (!isalnum(scopeName[i]) && scopeName[i] != GCF_SCOPE_NAME_SEP) { valid = false; } } } return valid; } + +// +// myHostname(giveFullname) +// +string myHostname(bool giveFullName) +{ + char fullhostname[300]; + if (gethostname(fullhostname, 300) != 0) { + return ("localhost"); + } + + if (!giveFullName) { + char* dot = strchr(fullhostname, '.'); + if (dot) { + *dot='\0'; + } + } + + return (fullhostname); +} } // namespace Common } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/Protocols/configure.in b/MAC/GCF/Protocols/configure.in index 3a1018c19e3150dc76c86fba3a7d5fa490887774..9e78fd0a032b97267b36acb5ddecd2472aff1a8c 100644 --- a/MAC/GCF/Protocols/configure.in +++ b/MAC/GCF/Protocols/configure.in @@ -39,8 +39,8 @@ dnl lofar_GENERAL lofar_INTERNAL(LCS/Common, Common, LCS-Common-2_3, 1,Common/LofarTypes.h,,) lofar_INTERNAL(LCS/Transport, transport, LCS-Transport-2_1, 1, Transport/DataHolder.h,,) -lofar_INTERNAL(MAC/GCF/GCFCommon, GCFCommon, MAC-GCF-6_2, 1,GCF/GCF_Defines.h,,) -lofar_INTERNAL(MAC/GCF/TM, GCFTM, MAC-GCF-6_2, 1, GCF/TM/GCF_Event.h,,) +lofar_INTERNAL(MAC/GCF/GCFCommon, GCFCommon, , 1,GCF/GCF_Defines.h,,) +lofar_INTERNAL(MAC/GCF/TM, GCFTM, , 1, GCF/TM/GCF_Event.h,,) dnl dnl Output Makefiles diff --git a/MAC/GCF/TM/configure.in b/MAC/GCF/TM/configure.in index 0fa4d932c30e7ffcc7eadab23e706dca8d2c1466..5dac09deb9613593dbd10887a1acc57c622b976a 100644 --- a/MAC/GCF/TM/configure.in +++ b/MAC/GCF/TM/configure.in @@ -37,7 +37,8 @@ dnl Check for LOFAR specific things dnl lofar_GENERAL lofar_INTERNAL(LCS/Common, Common, LCS-Common-2_3, 1, Common/LofarTypes.h,,) -lofar_INTERNAL(MAC/GCF/GCFCommon, GCFCommon, MAC-GCF-6_2, 1, GCF/GCF_Defines.h,,) +lofar_INTERNAL(LCS/ACC/APS, APS, ,1, APS/ParameterSet.h,,) +lofar_INTERNAL(MAC/GCF/GCFCommon, GCFCommon, , 1, GCF/GCF_Defines.h,,) dnl dnl Output Makefiles diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_DevicePort.h b/MAC/GCF/TM/include/GCF/TM/GCF_DevicePort.h index c84e2a278b11dc474a85d0535c010f7990463a33..86981b62c774c4bad3d9dadbdffa7e1f0042b44a 100644 --- a/MAC/GCF/TM/include/GCF/TM/GCF_DevicePort.h +++ b/MAC/GCF/TM/include/GCF/TM/GCF_DevicePort.h @@ -49,10 +49,10 @@ class GCFDevicePort : public GCFRawPort /// params see constructor of GCFPortInterface /// type is always SAP explicit GCFDevicePort (GCFTask& task, - string name, - int protocol, + const string& name, + int protocol, const string& deviceName, - bool transportRawData = false); + bool transportRawData = false); /** @param deviceName name of the file/device to open * GCFPortInterface params are: diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_ETHRawPort.h b/MAC/GCF/TM/include/GCF/TM/GCF_ETHRawPort.h index 37c9a1b91ef573827e91bcb0856c9dc6a78d09d9..5f95972029e25f8f755323b4e174cb40a5abf0ef 100644 --- a/MAC/GCF/TM/include/GCF/TM/GCF_ETHRawPort.h +++ b/MAC/GCF/TM/include/GCF/TM/GCF_ETHRawPort.h @@ -56,10 +56,10 @@ class GCFETHRawPort : public GCFRawPort public: // constructors && destructors /// params see constructor of GCFPortInterface - explicit GCFETHRawPort (GCFTask& task, - string name, - TPortType type, - bool transportRawData = false); + explicit GCFETHRawPort (GCFTask& task, + const string& name, + TPortType type, + bool transportRawData = false); /** default constructor * GCFPortInterface params are: diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_Port.h b/MAC/GCF/TM/include/GCF/TM/GCF_Port.h index 097ea16eb10a10338e8359f3eade2420be2976ba..857b1ce46251d6d3e21f6940d36ef3bb2dee0162 100644 --- a/MAC/GCF/TM/include/GCF/TM/GCF_Port.h +++ b/MAC/GCF/TM/include/GCF/TM/GCF_Port.h @@ -49,11 +49,11 @@ class GCFPort : public GCFPortInterface public: // constructor && destructor /// params see constructor of GCFPortInterface - explicit GCFPort (GCFTask& containertask, - string& name, - TPortType type, - int protocol, - bool transportRawData = false); + explicit GCFPort (GCFTask& containertask, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); /** default constructor * GCFPortInterface params are: @@ -77,11 +77,11 @@ class GCFPort : public GCFPortInterface public: // GCFPortInterface overloaded/defined methods /// params see constructor of GCFPortInterface - void init (GCFTask& containertask, - string name, - TPortType type, - int protocol, - bool transportRawData = false); + void init (GCFTask& containertask, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); /** * open/close methods @@ -118,9 +118,9 @@ class GCFPort : public GCFPortInterface private: // data members - string _remotetask; - string _remoteport; - GCFPortInterface* _pSlave; + string _remotetask; + string _remoteport; + GCFPortInterface* _pSlave; friend class GCFRawPort; // to access the setState method of the base class }; diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_PortInterface.h b/MAC/GCF/TM/include/GCF/TM/GCF_PortInterface.h index dab525f6e190ecaf593263d507a095afcb5b91d2..561037ab17217380e0fae4167fc742f70cce5c47 100644 --- a/MAC/GCF/TM/include/GCF/TM/GCF_PortInterface.h +++ b/MAC/GCF/TM/include/GCF/TM/GCF_PortInterface.h @@ -30,12 +30,9 @@ #include <Common/lofar_string.h> #include <GCF/GCF_Defines.h> -namespace LOFAR -{ - namespace GCF - { - namespace TM - { +namespace LOFAR { + namespace GCF { + namespace TM { // forward declacations class GCFTask; @@ -49,19 +46,16 @@ class GCFEvent; */ class GCFPortInterface { - public: - +public: /** port types */ - typedef enum TPortType - { + typedef enum TPortType { SAP = 1, /**< Service Access Point (port connector)*/ SPP, /**< Service Provision Point (port acceptor)*/ MSPP, /**< Multi Service Provision Point (port provider)*/ }; /** port states */ - typedef enum TSTATE - { + typedef enum TSTATE { S_DISCONNECTED, S_CONNECTING, S_CONNECTED, @@ -70,7 +64,7 @@ class GCFPortInterface }; /// destructor - virtual ~GCFPortInterface () {}; + virtual ~GCFPortInterface (); virtual bool close () = 0; virtual bool open () = 0; @@ -106,15 +100,21 @@ class GCFPortInterface /** * Attribute access functions */ - const string& getName () const {return _name;} - TPortType getType () const {return _type;} - bool isConnected () const {return _state == S_CONNECTED;} - TSTATE getState () const {return _state;} - const GCFTask* getTask () const {return _pTask;} - int getProtocol () const {return _protocol;} - bool isTransportRawData () const {return _transportRawData;} + const string& getName () const { return _name; } + TPortType getType () const { return _type; } + bool isConnected () const { return _state==S_CONNECTED; } + TSTATE getState () const { return _state; } + const GCFTask* getTask () const { return _pTask; } + int32 getProtocol () const { return _protocol; } + bool isTransportRawData () const { return _transportRawData; } + uint32 getInstanceNr() const { return _instanceNr; } + void setInstanceNr(uint32 nr) { _instanceNr = nr; } + string makeServiceName() const; + bool usesModernServiceName() const + { return (!_deviceNameMask.empty()); } - protected: // constructors +protected: + // constructors /** * @param pTask task on which the port is adapted * @param name name of the port @@ -125,54 +125,39 @@ class GCFPortInterface * not in the received data (unpacked in a GCFEvent) itself. In case of F_DATAIN * the user is responsible to flush the data from the incomming event buffer */ - explicit GCFPortInterface (GCFTask* pTask, - string name, - TPortType type, - int protocol, - bool transportRawData) : - _pTask(pTask), - _name(name), - _state(S_DISCONNECTED), - _type(type), - _protocol(protocol), - _transportRawData(transportRawData) - { - } + GCFPortInterface (GCFTask* pTask, + const string& name, + TPortType type, + int protocol, + bool transportRawData); + + // helper methods + virtual void setState (TSTATE newState) {_state = newState;} + + /** params see constructor */ + virtual void init(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); - private: + // data members + GCFTask* _pTask; + string _name; + string _deviceNameMask; + TSTATE _state; + TPortType _type; + int32 _protocol; /**< NOT USED */ + bool _transportRawData; + uint32 _instanceNr; + +private: /// default constructor is not allowed GCFPortInterface(); /// copying is not allowed GCFPortInterface (GCFPortInterface&); GCFPortInterface& operator=(GCFPortInterface&); - protected: // helper methods - virtual void setState (TSTATE newState) {_state = newState;} - - /** params see constructor */ - virtual void init(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData = false) - { - if (_state == S_DISCONNECTED) - { - _pTask = &task; - _name = name; - _type = type; - _protocol = protocol; - _transportRawData = transportRawData; - } - } - - protected: // data members - GCFTask* _pTask; - string _name; - TSTATE _state; - TPortType _type; - int _protocol; /**< NOT USED */ - bool _transportRawData; }; } // namespace TM } // namespace GCF diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_RawPort.h b/MAC/GCF/TM/include/GCF/TM/GCF_RawPort.h index be62eeee767e1c7a5bd93bb6b578dba3b88db8e1..4cb7c367ebf4a3ea6c110eb563e9fdd2daaa4a40 100644 --- a/MAC/GCF/TM/include/GCF/TM/GCF_RawPort.h +++ b/MAC/GCF/TM/include/GCF/TM/GCF_RawPort.h @@ -60,41 +60,20 @@ typedef struct */ class GCFRawPort : public GCFPortInterface { - protected: // consturctors && destructors - /// params see constructor of GCFPortInterface - explicit GCFRawPort (GCFTask& task, - string& name, - TPortType type, - int protocol, - bool transportRawData = false); - - /** default constructor - * GCFPortInterface params are: - * pTask => 0 - * name => "" - * type => SAP - * protocol => 0 - * transportRawData => false - */ - GCFRawPort(); - - private: - /// copying is not allowed. - GCFRawPort (const GCFRawPort&); - GCFRawPort& operator= (const GCFRawPort&); + // NOTE: constructors are protected !!! - public: +public: /// desctructor virtual ~GCFRawPort (); - public: // GCFPortInterface overloaded/defined methods - /// params see constructor of GCFPortInterface - void init (GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData = false); + void init (GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); + + // GCFPortInterface overloaded/defined methods /// these methods implements the final connection with the timer handler /// to realize the timer functionality @@ -112,9 +91,27 @@ class GCFRawPort : public GCFPortInterface void** arg = 0); virtual int cancelAllTimers (); - - protected: // helper methods +protected: + // constructors && destructors + /// params see constructor of GCFPortInterface + GCFRawPort (GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); + + /** default constructor + * GCFPortInterface params are: + * pTask => 0 + * name => "" + * type => SAP + * protocol => 0 + * transportRawData => false + */ + GCFRawPort(); + + // helper methods friend class GCFPort; // to access the setMaster method friend class GTMTimer; friend class GTMFile; @@ -123,7 +120,6 @@ class GCFRawPort : public GCFPortInterface void schedule_close(); void schedule_connected(); - bool isSlave () const {return _pMaster != 0;} virtual void setMaster (GCFPort* pMaster) {_pMaster = pMaster;} @@ -134,12 +130,17 @@ class GCFRawPort : public GCFPortInterface /// returns the original name of the port (given by the user). /// in case it is a slave port an extension is append to the original name - const string& getRealName() const; + string getRealName() const; - private: // data member - GCFPort* _pMaster; +private: + /// copying is not allowed. + GCFRawPort (const GCFRawPort&); + GCFRawPort& operator= (const GCFRawPort&); + + // data member + GCFPort* _pMaster; - private: // admin. data member + // admin. data member GTMTimerHandler* _pTimerHandler; }; } // namespace TM diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h b/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h index f43ea804ae2b045c04a9f1ccb44431ebf8ff69cd..20807888403ab8e0a30e8dfd45fa95272ac8ef10 100644 --- a/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h +++ b/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h @@ -25,18 +25,14 @@ #include <GCF/TM/GCF_RawPort.h> -namespace LOFAR -{ - namespace GCF - { +namespace LOFAR { + namespace GCF { - namespace SB - { + namespace SB { class GTMServiceBroker; } - namespace TM - { + namespace TM { // forward declaration class GCFTask; @@ -50,13 +46,13 @@ class GTMTCPSocket; */ class GCFTCPPort : public GCFRawPort { - public:// consturctors && destructors +public:// consturctors && destructors /// params see constructor of GCFPortInterface - explicit GCFTCPPort (GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData = false); + GCFTCPPort (GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); /** default constructor * GCFPortInterface params are: @@ -68,21 +64,21 @@ class GCFTCPPort : public GCFRawPort */ GCFTCPPort (); - private: +private: /// copying is not allowed. GCFTCPPort (const GCFTCPPort&); GCFTCPPort& operator= (const GCFTCPPort&); - public: +public: /// desctructor virtual ~GCFTCPPort (); - public: // GCFPortInterface overloaded/defined methods - void init (GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData = false); +public: // GCFPortInterface overloaded/defined methods + void init (GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData = false); /** * open/close methods @@ -96,7 +92,7 @@ class GCFTCPPort : public GCFRawPort virtual ssize_t send (GCFEvent& event); virtual ssize_t recv (void* buf, size_t count); - public: // GCFTCPPort specific methods +public: // GCFTCPPort specific methods virtual bool accept (GCFTCPPort& port); // addr is local address if getType == (M)SPP // addr is remote addres if getType == SAP @@ -106,17 +102,17 @@ class GCFTCPPort : public GCFRawPort string getHostName(); unsigned int getPortNumber(); - private: // helper methods +private: // helper methods friend class SB::GTMServiceBroker; void serviceRegistered(unsigned int result, unsigned int portNumber); void serviceUnregistered(); void serviceInfo(unsigned int result, unsigned int portNumber, const string& host); void serviceGone(); - protected: // data members +protected: // data members GTMTCPSocket* _pSocket; - private: +private: bool _addrIsSet; TPeerAddr _addr; string _host; diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_TimerPort.h b/MAC/GCF/TM/include/GCF/TM/GCF_TimerPort.h new file mode 100644 index 0000000000000000000000000000000000000000..57cec240840af49b0942d8376571b366d42b3c74 --- /dev/null +++ b/MAC/GCF/TM/include/GCF/TM/GCF_TimerPort.h @@ -0,0 +1,59 @@ +//# GCF_TimerPort.h: Port for attaching timers +//# +//# 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 GCF_TIMERPORT_H +#define GCF_TIMERPORT_H + +#include <GCF/TM/GCF_RawPort.h> +#include <GCF/TM/GCF_Event.h> +#include <GCF/TM/GCF_Task.h> +#include <Common/lofar_string.h> + +namespace LOFAR { + namespace GCF { + namespace TM { + +class GCFTimerPort : public GCFRawPort +{ +public: + /// constructor and desctructor + GCFTimerPort(GCFTask& aTask, const string& aName) : + GCFRawPort(aTask, aName, SAP, 0, false) {} + virtual ~GCFTimerPort () {} + + // GCFPortInterface overloaded/defined methods + virtual bool close () { return (false); } + virtual bool open () { return (false); } + virtual ssize_t send (GCFEvent& /*event*/) { return (0); } + virtual ssize_t recv (void* /*buf*/, size_t /*count*/) { return (0); } + +private: + /// copying is not allowed. + GCFTimerPort() : GCFRawPort() {} + GCFTimerPort (const GCFTimerPort&); + GCFTimerPort& operator= (const GCFTimerPort&); +}; + } // namespace TM + } // namespace GCF +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/TM/include/GCF/TM/Makefile.am b/MAC/GCF/TM/include/GCF/TM/Makefile.am index fe62175cbbd5aace46a530187fefa0cff4df0cd9..461ea814172ffe3136f5bb298e256f5e1546fbd4 100644 --- a/MAC/GCF/TM/include/GCF/TM/Makefile.am +++ b/MAC/GCF/TM/include/GCF/TM/Makefile.am @@ -6,6 +6,7 @@ pkginclude_HEADERS = \ GCF_TCPPort.h \ GCF_RawPort.h \ GCF_Port.h \ + GCF_TimerPort.h \ GCF_PortInterface.h \ GCF_Event.h \ GCF_Protocols.h \ diff --git a/MAC/GCF/TM/src/GCF_Task.cc b/MAC/GCF/TM/src/GCF_Task.cc index 3fc59b1198fa4b4848f9c8e475ba3d9e125ad2f5..aba8a0af3c6f6693d66d9caf3d2f743acc3cf265 100644 --- a/MAC/GCF/TM/src/GCF_Task.cc +++ b/MAC/GCF/TM/src/GCF_Task.cc @@ -30,8 +30,10 @@ #include <GCF/TM/GCF_PortInterface.h> -#include <GCF/ParameterSet.h> #include <Common/lofar_fstream.h> +#include <Common/LofarLocators.h> +#include <APS/ParameterSet.h> +using LOFAR::ACC::APS::ParameterSet; using std::ifstream; #include <signal.h> @@ -68,50 +70,31 @@ GCFTask::~GCFTask() void GCFTask::init(int argc, char** argv) { - _argc = argc; - _argv = argv; - - string procName(argv[0]); - - ifstream logPropFile; - - // Construct the etc path for config files - string etcPath(procName); - // Find last '/' - string::size_type pos = etcPath.rfind('/'); - if (pos == string::npos) pos = 0; // not found: so erase whole filename - else pos++; // found : increase pos to avoid erasing the '/' too - - if (pos == 0 || pos == 1) etcPath = "/etc/"; // no '/' or only one '/' (at the 0 position) - else - { - etcPath.erase(pos); - etcPath += "../etc/"; // becomes e.g. /opt/lofar/bin/../etc/ - } - - procName.erase(0, pos); // erase path - - // Try to open the log_prop file, if process has its own log_prop file then use it in - // the INIT_LOGGER otherwise use the default mac.log_prop - string logPropFileName = etcPath + procName + ".log_prop"; - logPropFile.open(logPropFileName.c_str(), ifstream::in); - if (!logPropFile) - { - logPropFileName = etcPath + "mac.log_prop"; - } - else - { - logPropFile.close(); - } - - INIT_LOGGER(logPropFileName.c_str()); - - ParameterSet* pParamSet = ParameterSet::instance(); - pParamSet->setSearchPath(etcPath); - pParamSet->adoptFile(procName + ".conf"); - - if (_doExit) - exit(-1); + _argc = argc; + _argv = argv; + + // Try to open the log_prop file, if process has its own log_prop file then use it + // the INIT_LOGGER otherwise use the default mac.log_prop + ConfigLocator aCL; + string procName(basename(argv[0])); + string logPropFile(procName + ".log_prop"); + // First try logpropfile <task>.log_prop + if (aCL.locate(logPropFile) == "") { + // locator could not find it try defaultname + logPropFile = "mac.log_prop"; + } + INIT_LOGGER(aCL.locate(logPropFile).c_str()); + LOG_DEBUG_STR ("Initialized logsystem with: " << aCL.locate(logPropFile)); + + // Read in the ParameterSet of the task (<task>.conf) + ParameterSet* pParamSet = ACC::APS::globalParameterSet(); + string configFile(aCL.locate(procName + ".conf")); + LOG_DEBUG_STR ("Using parameterfile: " << configFile); + pParamSet->adoptFile(configFile); + + if (_doExit) { + exit(-1); + } } void GCFTask::run() diff --git a/MAC/GCF/TM/src/Makefile.am b/MAC/GCF/TM/src/Makefile.am index 9017b31d77bdebb7e97140d61ada282248944674..ef13af67a6a2647645cd544a128cc1ad1595e195 100644 --- a/MAC/GCF/TM/src/Makefile.am +++ b/MAC/GCF/TM/src/Makefile.am @@ -26,6 +26,7 @@ libgcftm_la_SOURCES= $(DOCHDRS) \ GCF_Protocols.cc \ GCF_Task.cc \ GCF_Event.cc \ + Port/GCF_PortInterface.cc \ Port/GCF_Port.cc \ Port/GCF_RawPort.cc \ Timer/GTM_Timer.cc \ diff --git a/MAC/GCF/TM/src/Port/GCF_Port.cc b/MAC/GCF/TM/src/Port/GCF_Port.cc index c0e1da20c0d9a62abb9ec54c2293279546dab208..ba301e1327e578dc666b34bbb325e7941c70f413 100644 --- a/MAC/GCF/TM/src/Port/GCF_Port.cc +++ b/MAC/GCF/TM/src/Port/GCF_Port.cc @@ -27,303 +27,345 @@ #include <GCF/TM/GCF_Task.h> #include <GCF/TM/GCF_Event.h> #include <GCF/TM/GCF_Protocols.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> #include <GTM_Defines.h> #include <GCF/TM/GCF_TCPPort.h> #include <GCF/TM/GCF_ETHRawPort.h> #include <GCF/TM/GCF_DevicePort.h> -namespace LOFAR -{ - namespace GCF - { - namespace TM - { - -GCFPort::GCFPort(GCFTask& task, - string& name, - TPortType type, - int protocol, - bool transportRawData) : - GCFPortInterface(&task, name, type, protocol, transportRawData), _pSlave(0) +namespace LOFAR { + using namespace ACC::APS; + namespace GCF { + namespace TM { + +// +// GCFPort(task, name, type, protocol, raw) +// +GCFPort::GCFPort(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) : + GCFPortInterface(&task, name, type, protocol, transportRawData), _pSlave(0) { + // When modern name is used this name contains the complete servicename + // Store this info in the remotexxx variables. + string::size_type colon = name.find(":",0); + if (colon != string::npos) { + _remotetask = name.substr(0,colon); + _remoteport = name.substr(colon+1); + } } +// +// GCFPort() +// GCFPort::GCFPort() : GCFPortInterface(0, "", SAP, 0, false), _pSlave(0) { } +// +// ~GCFPort() +// GCFPort::~GCFPort() { - // - // if the open method on the port has been called, there will be - // a slave port which needs to be cleaned up. - // - if (_pSlave) delete _pSlave; - _pSlave = 0; + // + // if the open method on the port has been called, there will be + // a slave port which needs to be cleaned up. + // + if (_pSlave) { + delete _pSlave; + } + _pSlave = 0; } -void GCFPort::init(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData) +// +// init (task, name, type, protocol, raw) +// +void GCFPort::init(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) { - GCFPortInterface::init(task, name, type, protocol, transportRawData); - if (_pSlave) delete _pSlave; - _pSlave = 0; + GCFPortInterface::init(task, name, type, protocol, transportRawData); + if (_pSlave) { + delete _pSlave; + } + _pSlave = 0; + + // When modern name is used this name contains the complete servicename + // Store this info in the remotexxx variables. + string::size_type colon = name.find(":",0); + if (colon != string::npos) { + _remotetask = name.substr(0,colon); + _remoteport = name.substr(colon+1); + } } +// +// open() +// bool GCFPort::open() { - if (_state != S_DISCONNECTED && _state != S_CONNECTED) - { - return false; - } - if (MSPP == getType()) - { - LOG_ERROR("Ports of type MSPP should not be initialised directly via this common port"); - return false; - } - _state = S_CONNECTING; - - // - // If the port has been openend before then the _pSlave port has already - // been connected, and we don't need to connect it again. We can simply - // call the ::open() method on the slave and return. - // - if (_pSlave) return _pSlave->open(); - - // - // This is the first call to open. - // Determine what kind of slave port to create and open it. - // - - string typeParam = formatString( - PARAM_PORT_PROT_TYPE, - _pTask->getName().c_str(), - _name.c_str()); - string protType; - TPeerAddr addr; - try - { - protType = ParameterSet::instance()->getString(typeParam); - } - catch (...) - { - if (SAP == getType()) - { - // try to retrive the protType via the remote server name - string remoteServiceNameParam = formatString( - PARAM_SERVER_SERVICE_NAME, - _pTask->getName().c_str(), - _name.c_str()); - try - { - // remote service is set by user? - if (_remotetask.length() > 0 && _remoteport.length() > 0) - { - addr.taskname = _remotetask; - addr.portname = _remoteport; - } - else - { - // retrieve remote service addr from parameter set - string remoteAddr; - remoteAddr += ParameterSet::instance()->getString(remoteServiceNameParam); - const char* pRemoteTaskName = remoteAddr.c_str(); - // format is: "<taskname>:<portname>" - char* colon = strchr(pRemoteTaskName, ':'); - if (colon) *colon = '\0'; - addr.taskname = pRemoteTaskName; - addr.portname = colon + 1; - } - - // now the protType of the remote service port can be retrieved from the - // parameter set - typeParam = formatString( - PARAM_PORT_PROT_TYPE, - addr.taskname.c_str(), - addr.portname.c_str()); - protType = ParameterSet::instance()->getString(typeParam); - } - catch (...) - { - LOG_ERROR(formatString ( - "Could not find port info for port '%s' of task '%s via (%s:%s)'.", - _name.c_str(), _pTask->getName().c_str(), - addr.taskname.c_str(), - addr.portname.c_str())); - - return false; - } - } - else - { - LOG_ERROR(formatString ( - "Could not find port info for port '%s' of task '%s'.", - _name.c_str(), _pTask->getName().c_str())); - - return false; - } - } - - // Check for the various port types - if (protType == "TCP") - { - GCFTCPPort* pNewPort(0); - string pseudoName = _name + "_TCP"; - pNewPort = new GCFTCPPort(*_pTask, pseudoName, _type, _protocol, _transportRawData); - if (_remotetask.length() > 0 && _remoteport.length() > 0) - { - addr.taskname = _remotetask; - addr.portname = _remoteport; - pNewPort->setAddr(addr); - } - pNewPort->setMaster(this); - - _pSlave = pNewPort; - } - else if (protType == "ETH") - { - GCFETHRawPort* pNewPort(0); - string pseudoName = _name + "_ETH"; - pNewPort = new GCFETHRawPort(*_pTask, pseudoName, _type, _transportRawData); - pNewPort->setMaster(this); - - _pSlave = pNewPort; - } - else if (protType == "DEV") - { - GCFDevicePort* pNewPort(0); - string pseudoName = _name + "_DEV"; - pNewPort = new GCFDevicePort(*_pTask, pseudoName, 0, "", _transportRawData); - pNewPort->setMaster(this); - - _pSlave = pNewPort; - } - else - { - LOG_ERROR(formatString ( - "No implementation found for port protocol type '%s'. At this moment only TCP, DEV and ETH is supported!", - protType.c_str())); - - return false; - } - - return _pSlave->open(); + if (_state != S_DISCONNECTED && _state != S_CONNECTED) { + return (false); + } + + if (getType() == MSPP) { // listener + LOG_ERROR("Ports of type MSPP should not be initialised directly via this common port"); + return (false); + } + _state = S_CONNECTING; + + // + // If the port has been openend before then the _pSlave port has already + // been connected, and we don't need to connect it again. We can simply + // call the ::open() method on the slave and return. + // + if (_pSlave) { + return (_pSlave->open()); + } + + // + // This is the first call to open. + // Determine what KIND OF SLAVE PORT to create and open it. + // + string typeParam = formatString (PARAM_PORT_PROT_TYPE, + _pTask->getName().c_str(), _name.c_str()); + string protType(""); + TPeerAddr addr; + // try mac.ns.<taskname>.<name>.type in parameterSet + if (globalParameterSet()->isDefined(typeParam)) { + protType = globalParameterSet()->getString(typeParam); + } + else { + // remote service is set by user? + if (_remotetask.length() > 0 && _remoteport.length() > 0) { + addr.taskname = _remotetask; + addr.portname = _remoteport; + } + else { + // try to retrieve remote service addr from parameter set + // mac.top.<taskname>.<name>.remoteservice + string remoteServiceNameParam = + formatString(PARAM_SERVER_SERVICE_NAME, + _pTask->getName().c_str(), _name.c_str()); + string remoteAddr; + if (globalParameterSet()->isDefined(remoteServiceNameParam)) { + remoteAddr = globalParameterSet()->getString(remoteServiceNameParam); + // format is: "<taskname>:<portname>" + string::size_type colon = remoteAddr.find(":",0); + if (colon != string::npos) { + addr.taskname = remoteAddr.substr(0,colon); + addr.portname = remoteAddr.substr(colon+1); + _deviceNameMask = remoteAddr; + } + } + } + + // found addr information? + if (addr.taskname.length() > 0 && addr.portname.length() > 0) { + // now the protType of the remote service port can be + // retrieved from the parameter set + // try mac.ns.<taskname>.<name>.type in parameterSet + typeParam = formatString (PARAM_PORT_PROT_TYPE, + addr.taskname.c_str(), addr.portname.c_str()); + if (globalParameterSet()->isDefined(typeParam)) { + protType = globalParameterSet()->getString(typeParam); + } + } + } + + // When protType is not set after this effort use TCP. + if (protType.length() <= 1) { + LOG_DEBUG(formatString ("No port info for port '%s', using TCP", + makeServiceName().c_str())); + protType = "TCP"; + } + + // 'protType' is now set, check for the various port types + if (protType == "TCP") { + GCFTCPPort* pNewPort(0); +// if (usesModernServiceName()) { + pNewPort = new GCFTCPPort(*_pTask, makeServiceName(), _type, + _protocol, _transportRawData); +// } +// else { +// pNewPort = new GCFTCPPort(*_pTask, _name+"_TCP", _type, +// _protocol, _transportRawData); +// } + + if (_remotetask.length() > 0 && _remoteport.length() > 0) { + addr.taskname = _remotetask; + addr.portname = _remoteport; + pNewPort->setAddr(addr); + } + pNewPort->setMaster(this); + pNewPort->setInstanceNr(getInstanceNr()); + + _pSlave = pNewPort; + } + else if (protType == "ETH") { + GCFETHRawPort* pNewPort(0); + string pseudoName = _name + "_ETH"; + pNewPort = new GCFETHRawPort(*_pTask, pseudoName, _type, _transportRawData); + pNewPort->setMaster(this); + + _pSlave = pNewPort; + } + else if (protType == "DEV") { + GCFDevicePort* pNewPort(0); + string pseudoName = _name + "_DEV"; + pNewPort = new GCFDevicePort(*_pTask, pseudoName, 0, "", _transportRawData); + pNewPort->setMaster(this); + + _pSlave = pNewPort; + } + else { + ASSERTSTR(false, "No implementation found for port protocol type '" << + protType << "'. Only TCP, DEV and ETH are supported!"); + return (false); + } + + return (_pSlave->open()); } +// +// close() +// bool GCFPort::close() { - _state = S_CLOSING; - if (!_pSlave) - { - LOG_WARN("Was not opened!!!"); - - return false; - } - - return _pSlave->close(); + _state = S_CLOSING; + if (!_pSlave) { + LOG_DEBUG("Port was not opened!!!"); + return (false); + } + + return (_pSlave->close()); } +// +// setRemoteAddr(task, port) +// bool GCFPort::setRemoteAddr(const string& remotetask, const string& remoteport) { - if (_type == SAP) - { - _remotetask = remotetask; - _remoteport = remoteport; - return (_remotetask.length() > 0 && _remoteport.length() > 0); - } - return false; + if (_type == SAP) { + _remotetask = remotetask; + _remoteport = remoteport; + return (_remotetask.length() > 0 && _remoteport.length() > 0); + } + return false; } +// +// send(event) +// ssize_t GCFPort::send(GCFEvent& e) { - if (!_pSlave || !isConnected()) - { - LOG_ERROR(formatString ( - "Port '%s' on task '%s' not connected! Event not sent!", - getName().c_str(), - getTask()->getName().c_str())); - return 0; - } - - if (SPP == _type) - { - if (!(F_EVT_INOUT(e) & F_OUT)) - { - LOG_ERROR(formatString ( - "Trying to send IN event '%s' on SPP " - "port '%s'; discarding this event.", - getTask()->evtstr(e), _name.c_str())); - - return -1; - } - } - else if (SAP == _type) - { - if (!(F_EVT_INOUT(e) & F_IN)) - { - LOG_ERROR(formatString ( - "Trying to send OUT event '%s' on SAP " - "port '%s'; discarding this event.", - getTask()->evtstr(e), _name.c_str())); - - return -1; - } - } - else if (MSPP == _type) - { - LOG_ERROR(formatString ( - "Trying to send event '%s' by means of the portprovider: %s (MSPP). " - "Not supported yet", - getTask()->evtstr(e), _name.c_str())); - - return -1; - } - - return _pSlave->send(e); + if (!_pSlave || !isConnected()) { + LOG_ERROR(formatString ("Port '%s' of task '%s' not connected! Event not sent!", + makeServiceName().c_str(), getTask()->getName().c_str())); + return (0); + } + + if (SPP == _type) { + if (!(F_EVT_INOUT(e) & F_OUT)) { + LOG_ERROR(formatString ("Trying to send IN event '%s' on SPP " + "port '%s'; discarding this event.", + getTask()->evtstr(e), makeServiceName().c_str())); + + return (-1); + } + } + else if (SAP == _type) { + if (!(F_EVT_INOUT(e) & F_IN)) { + LOG_ERROR(formatString ("Trying to send OUT event '%s' on SAP " + "port '%s'; discarding this event.", + getTask()->evtstr(e), makeServiceName().c_str())); + + return (-1); + } + } + else if (MSPP == _type) { + LOG_ERROR(formatString ("Trying to send event '%s' by means of " + "the portprovider: %s (MSPP). " + "Not supported yet", + getTask()->evtstr(e), makeServiceName().c_str())); + + return (-1); + } + return (_pSlave->send(e)); } +// +// recv (buf, count) +// ssize_t GCFPort::recv(void* buf, size_t count) { - if (!_pSlave) return -1; - return _pSlave->recv(buf, count); + if (!_pSlave) { + return (-1); + } + + return (_pSlave->recv(buf, count)); } +// +// setTimer(sec, usec, itvsec, itvusec, arg) +// long GCFPort::setTimer(long delay_sec, long delay_usec, - long interval_sec, long interval_usec, - void* arg) + long interval_sec, long interval_usec, + void* arg) { - if (!_pSlave) return -1; - return _pSlave->setTimer(delay_sec, delay_usec, - interval_sec, interval_usec, - arg); + if (!_pSlave) { + return (-1); + } + + return (_pSlave->setTimer(delay_sec, delay_usec, + interval_sec, interval_usec, arg)); } +// +// setTimer(seconds, interval, args) +// long GCFPort::setTimer(double delay_seconds, - double interval_seconds, - void* arg) + double interval_seconds, + void* arg) { - if (!_pSlave) return -1; - return _pSlave->setTimer(delay_seconds, interval_seconds, arg); + if (!_pSlave) { + return (-1); + } + + return (_pSlave->setTimer(delay_seconds, interval_seconds, arg)); } +// +// cancelTimer(timerid, arg) +// int GCFPort::cancelTimer(long timerid, void **arg) { - if (!_pSlave) return -1; - return _pSlave->cancelTimer(timerid, arg); + if (!_pSlave) { + return (-1); + } + + return (_pSlave->cancelTimer(timerid, arg)); } +// +// cancelAllTimers +// int GCFPort::cancelAllTimers() { - if (!_pSlave) return -1; - return _pSlave->cancelAllTimers(); + if (!_pSlave) { + return (-1); + } + + return (_pSlave->cancelAllTimers()); } + } // namespace TM } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/TM/src/Port/GCF_PortInterface.cc b/MAC/GCF/TM/src/Port/GCF_PortInterface.cc new file mode 100644 index 0000000000000000000000000000000000000000..bf23126559f226dc08e86f89d88cb7a64862f365 --- /dev/null +++ b/MAC/GCF/TM/src/Port/GCF_PortInterface.cc @@ -0,0 +1,116 @@ +//# GCF_PortInterface.cc: container class for all port implementations +//# +//# 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$ + +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> + +//# Includes +#include <sys/types.h> +#include <sys/uio.h> +#include <string.h> + +#include <Common/lofar_string.h> +#include <GCF/GCF_Defines.h> +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_PortInterface.h> + +namespace LOFAR { + namespace GCF { + namespace TM { + +// +// ~GCFPortInterface() +// +GCFPortInterface::~GCFPortInterface () +{ } + +// +// GCFPortInterface(task, name, type, protocol ,raw) +// +GCFPortInterface::GCFPortInterface (GCFTask* pTask, + const string& name, + TPortType type, + int protocol, + bool transportRawData) : + _pTask(pTask), + _name(name), + _deviceNameMask(), + _state(S_DISCONNECTED), + _type(type), + _protocol(protocol), + _transportRawData(transportRawData), + _instanceNr(0) +{ + if (_name.find(":",0) != string::npos) { // colon in _name? + _deviceNameMask = _name; // name is also the mask + } +} + +// +// init(task, name, type, protocol ,raw) +// +void GCFPortInterface::init(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) +{ + if (_state == S_DISCONNECTED) { + _pTask = &task; + _name = name; + _type = type; + _protocol = protocol; + _transportRawData = transportRawData; + _instanceNr = 0; + if (_name.find(":",0) != string::npos) { // colon in _name? + _deviceNameMask = _name; // name is also the mask + } + else { + _deviceNameMask = ""; // clear mask + } + } +} + +// +// makeServiceName() +// +// Construct the ServiceName from the taskname and the _name OR +// from the instanceNr and the _name +// +string GCFPortInterface::makeServiceName() const +{ + if (!_deviceNameMask.empty()) { + // use instanceNr and _name to construct the servicename + string instanceNrStr; + if (_instanceNr) { + instanceNrStr = toString(_instanceNr); + } + return(formatString(_deviceNameMask.c_str(), instanceNrStr.c_str())); + } + + // no colon in _name, use old-style taskname and _name construction + return(formatString("%s:%s", _pTask->getName().c_str(), _name.c_str())); +} + + } // namespace TM + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/TM/src/Port/GCF_RawPort.cc b/MAC/GCF/TM/src/Port/GCF_RawPort.cc index 51e3c647bfc7571e2326c1fb25371b4e8845615d..8fa8695d6b0c8acf765d0a8ce062ed3d15fea4eb 100644 --- a/MAC/GCF/TM/src/Port/GCF_RawPort.cc +++ b/MAC/GCF/TM/src/Port/GCF_RawPort.cc @@ -29,310 +29,332 @@ #include <GCF/TM/GCF_Protocols.h> #include <GTM_Defines.h> #include <Timer/GTM_TimerHandler.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> -namespace LOFAR -{ - namespace GCF - { - namespace TM - { +namespace LOFAR { + using namespace ACC::APS; + namespace GCF { + namespace TM { // static framework events static GCFEvent disconnectedEvent(F_DISCONNECTED); static GCFEvent connectedEvent (F_CONNECTED); static GCFEvent closedEvent (F_CLOSED); -GCFRawPort::GCFRawPort(GCFTask& task, - string& name, - TPortType type, - int protocol, - bool transportRawData) : +// +// GCFRawPort(task, name, type, protocol, raw) +// +GCFRawPort::GCFRawPort(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) : GCFPortInterface(&task, name, type, protocol, transportRawData), _pMaster(0) { - _pTimerHandler = GTMTimerHandler::instance(); - ASSERT(_pTimerHandler); + _pTimerHandler = GTMTimerHandler::instance(); + ASSERT(_pTimerHandler); } +// +// GCFRawPort() +// GCFRawPort::GCFRawPort() : GCFPortInterface(0, "", SAP, 0, false), _pMaster(0) { - _pTimerHandler = GTMTimerHandler::instance(); - ASSERT(_pTimerHandler); + _pTimerHandler = GTMTimerHandler::instance(); + ASSERT(_pTimerHandler); } -void GCFRawPort::init(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData) +// +// GCFRawPort(task, name, type, protocol, raw) +// +void GCFRawPort::init(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) { GCFPortInterface::init(task, name, type, protocol, transportRawData); _pMaster = 0; } +// +// ~GCFRawPort() +// GCFRawPort::~GCFRawPort() { - cancelAllTimers(); - ASSERT(_pTimerHandler); - GTMTimerHandler::release(); - _pTimerHandler = 0; + cancelAllTimers(); + ASSERT(_pTimerHandler); + GTMTimerHandler::release(); + _pTimerHandler = 0; } +// +// dispatch(event) +// GCFEvent::TResult GCFRawPort::dispatch(GCFEvent& event) { - GCFEvent::TResult status = GCFEvent::NOT_HANDLED; - ASSERT(_pTask); - - // Test whether the event is a framework event or not - if ((F_DATAIN != event.signal) && - (F_DATAOUT != event.signal) && - (F_EVT_PROTOCOL(event) != F_FSM_PROTOCOL) && - (F_EVT_PROTOCOL(event) != F_PORT_PROTOCOL)) - { - // Inform about the fact of an incomming message - LOG_DEBUG(formatString ( - "%s was received on port '%s' in task '%s'", - _pTask->evtstr(event), - getRealName().c_str(), - _pTask->getName().c_str())); - } - - switch (event.signal) - { - case F_CONNECTED: - LOG_INFO(formatString ( - "Port '%s' in task '%s' is connected!", - getRealName().c_str(), _pTask->getName().c_str())); - _state = S_CONNECTED; - break; - - case F_DISCONNECTED: - case F_CLOSED: - LOG_INFO(formatString ( - "Port '%s' in task '%s' is %s!", - getRealName().c_str(), _pTask->getName().c_str(), - (event.signal == F_CLOSED ? "closed" : "disconnected"))); - _state = S_DISCONNECTED; - break; - - case F_TIMER: - { - // result of the schedule_* methods - GCFTimerEvent* pTE = static_cast<GCFTimerEvent*>(&event); - if (&disconnectedEvent == pTE->arg || - &connectedEvent == pTE->arg || - &closedEvent == pTE->arg) - { - return dispatch(*((GCFEvent*) pTE->arg)); - } - break; - } - case F_DATAIN: - { - // the specific transport implementations informs the rawport about - // incomming data - if (!isTransportRawData()) - { - // user of the port wants to receive GCFEvent formed events - return recvEvent(); // implicits indirect call of this dispatch - } - break; - } - default: - if (SPP == getType() && (F_EVT_INOUT(event) == F_OUT)) - { - LOG_ERROR(formatString ( - "Developer error in %s (port %s): received an OUT event (%s) in a SPP", - _pTask->getName().c_str(), - getRealName().c_str(), - _pTask->evtstr(event) - )); - return status; - } - else if (SAP == getType() && (F_EVT_INOUT(event) == F_IN)) - { - LOG_ERROR(formatString ( - "Developer error in %s (port %s): received an IN event (%s) in a SAP", - _pTask->getName().c_str(), - getRealName().c_str(), - _pTask->evtstr(event) - )); - return status; - } - break; - } - - if (isSlave()) - { - _pMaster->setState(_state); - status = _pTask->dispatch(event, *_pMaster); - } - else - { - status = _pTask->dispatch(event, *this); - } - - return status; + GCFEvent::TResult status = GCFEvent::NOT_HANDLED; + ASSERT(_pTask); + + // Test whether the event is a framework event or not + if ((F_DATAIN != event.signal) && (F_DATAOUT != event.signal) && + (F_EVT_PROTOCOL(event) != F_FSM_PROTOCOL) && + (F_EVT_PROTOCOL(event) != F_PORT_PROTOCOL)) { + // Inform about the fact of an incomming message + LOG_DEBUG(formatString ("%s was received on port '%s' in task '%s'", + _pTask->evtstr(event), + getRealName().c_str(), + _pTask->getName().c_str())); + } + + switch (event.signal) { + case F_CONNECTED: + LOG_TRACE_STAT(formatString ("Port '%s' in task '%s' is connected!", + getRealName().c_str(), _pTask->getName().c_str())); + _state = S_CONNECTED; + break; + + case F_DISCONNECTED: + case F_CLOSED: + LOG_TRACE_STAT(formatString ("Port '%s' in task '%s' is %s!", + getRealName().c_str(), _pTask->getName().c_str(), + (event.signal == F_CLOSED ? "closed" : "disconnected"))); + _state = S_DISCONNECTED; + break; + + case F_TIMER: { + // result of the schedule_* methods + GCFTimerEvent* pTE = static_cast<GCFTimerEvent*>(&event); + if (&disconnectedEvent == pTE->arg || &connectedEvent == pTE->arg || + &closedEvent == pTE->arg) { + return dispatch(*((GCFEvent*) pTE->arg)); + } + break; + } + + case F_DATAIN: { + // the specific transport implementations informs the rawport about + // incomming data + if (!isTransportRawData()) { + // user of the port wants to receive GCFEvent formed events + return recvEvent(); // implicits indirect call of this dispatch + } + break; + } + + default: + if (SPP == getType() && (F_EVT_INOUT(event) == F_OUT)) { + LOG_ERROR(formatString ("Developer error in %s (port %s): " + "received an OUT event (%s) in a SPP", + _pTask->getName().c_str(), + getRealName().c_str(), + _pTask->evtstr(event))); + return (status); + } + else if (SAP == getType() && (F_EVT_INOUT(event) == F_IN)) { + LOG_ERROR(formatString ("Developer error in %s (port %s): " + "received an IN event (%s) in a SAP", + _pTask->getName().c_str(), + getRealName().c_str(), + _pTask->evtstr(event))); + return (status); + } + break; + } + + if (isSlave()) { + _pMaster->setState(_state); + status = _pTask->dispatch(event, *_pMaster); + } + else { + status = _pTask->dispatch(event, *this); + } + + return (status); } +// +// settimer(sec, usec, itvsec, itvusec, arg) +// long GCFRawPort::setTimer(long delay_sec, long delay_usec, - long interval_sec, long interval_usec, - void* arg) + long interval_sec, long interval_usec, + void* arg) { - ASSERT(_pTimerHandler); - uint64 delay(delay_sec); - uint64 interval(interval_sec); - delay *= 1000000; - interval *= 1000000; - delay += (uint64) delay_usec; - interval += (uint64) interval_usec; - return _pTimerHandler->setTimer(*this, - delay, - interval, - arg); + ASSERT(_pTimerHandler); + uint64 delay(delay_sec); + uint64 interval(interval_sec); + delay *= 1000000; + interval *= 1000000; + delay += (uint64) delay_usec; + interval += (uint64) interval_usec; + + return (_pTimerHandler->setTimer(*this, delay, interval, arg)); } +// +// setTimer(sec, itvsec, arg) +// long GCFRawPort::setTimer(double delay_seconds, - double interval_seconds, - void* arg) + double interval_seconds, + void* arg) { ASSERT(_pTimerHandler); - return _pTimerHandler->setTimer(*this, - (uint64) (delay_seconds * 1000000.0), - (uint64) (interval_seconds * 1000000.0), - arg); + + return (_pTimerHandler->setTimer(*this, + (uint64) (delay_seconds * 1000000.0), + (uint64) (interval_seconds * 1000000.0), + arg)); } +// +// cancelTimer(timerid, arg) +// int GCFRawPort::cancelTimer(long timerid, void **arg) { ASSERT(_pTimerHandler); return _pTimerHandler->cancelTimer(timerid, arg); } +// +// cancelAllTimers() +// int GCFRawPort::cancelAllTimers() { ASSERT(_pTimerHandler); return _pTimerHandler->cancelAllTimers(*this); } +// +// findAddr(addr) +// bool GCFRawPort::findAddr(TPeerAddr& addr) { - // find remote address - string remoteAddrParam = formatString( - PARAM_SERVER_SERVICE_NAME, - _pTask->getName().c_str(), - getRealName().c_str()); - - addr.taskname = ""; - addr.portname = ""; - - if (SAP == _type) - { - string remoteAddr; - try - { - remoteAddr += ParameterSet::instance()->getString(remoteAddrParam); - } - catch (...) - { - LOG_DEBUG(formatString ( - "No remote address found for port '%s' of task '%s'", - getRealName().c_str(), _pTask->getName().c_str())); - - return false; - } - - const char* pRemoteTaskName = remoteAddr.c_str(); - // format is: "<taskname>:<portname>" - char* colon = strchr(pRemoteTaskName, ':'); - if (colon) *colon = '\0'; - - addr.taskname = pRemoteTaskName; - addr.portname = colon + 1; - } - else - { - return false; - } - - return true; + // find remote address + addr.taskname = ""; + addr.portname = ""; + + if (_type != SAP) { + return (false); + } + + string remoteAddr; + // try mac.top.<taskname>.<name>.remoteservice in parameterSet + string remoteAddrParam = formatString(PARAM_SERVER_SERVICE_NAME, + _pTask->getName().c_str(), getRealName().c_str()); + if (globalParameterSet()->isDefined(remoteAddrParam)) { + remoteAddr = globalParameterSet()->getString(remoteAddrParam); + } + else { + LOG_DEBUG(formatString( + "No remote address found for port '%s' of task '%s'", + getRealName().c_str(), _pTask->getName().c_str())); + return (false); + } + + // format is: "<taskname>:<portname>" + string::size_type colon = remoteAddr.find(":",0); + if (colon == string::npos) { + return (false); + } + addr.taskname = remoteAddr.substr(0,colon); + addr.portname = remoteAddr.substr(colon+1); + + return (true); } +// +// schedule_disconnect() +// void GCFRawPort::schedule_disconnected() { // forces a context switch setTimer(0, 0, 0, 0, (void*)&disconnectedEvent); } +// +// schedule_close() +// void GCFRawPort::schedule_close() { // forces a context switch setTimer(0, 0, 0, 0, (void*)&closedEvent); } +// +// schedule_connect() +// void GCFRawPort::schedule_connected() { // forces a context switch setTimer(0, 0, 0, 0, (void*)&connectedEvent); } +// +// recvEvent() +// GCFEvent::TResult GCFRawPort::recvEvent() { - GCFEvent::TResult status = GCFEvent::NOT_HANDLED; - - GCFEvent e; - // expects and reads signal - if (recv(&e.signal, sizeof(e.signal)) != sizeof(e.signal)) - { - // don't continue with receiving - } - // expects and reads length - else if (recv(&e.length, sizeof(e.length)) != sizeof(e.length)) - { - // don't continue with receiving - } - // reads payload if specified - else if (e.length > 0) - { - GCFEvent* full_event = 0; - char* event_buf = new char[sizeof(e) + e.length]; - full_event = (GCFEvent*)event_buf; - memcpy(event_buf, &e, sizeof(e)); - - // read the payload right behind the just memcopied basic event structure - if (recv(event_buf + sizeof(e), e.length) > 0) - { - // dispatchs an event with just received params - status = dispatch(*full_event); - } - delete [] event_buf; - } - // dispatchs an event without params - else - { - status = dispatch(e); - } - - if (status != GCFEvent::HANDLED) - { - ASSERT(getTask()); - LOG_INFO(formatString ( - "'%s' for port '%s' in task '%s' not handled or an error occured", - getTask()->evtstr(e), - getRealName().c_str(), - getTask()->getName().c_str())); - } - - return status; + GCFEvent::TResult status = GCFEvent::NOT_HANDLED; + + GCFEvent e; + // expects and reads signal + if (recv(&e.signal, sizeof(e.signal)) != sizeof(e.signal)) { + // don't continue with receiving + } + // expects and reads length + else if (recv(&e.length, sizeof(e.length)) != sizeof(e.length)) { + // don't continue with receiving + } + // reads payload if specified + else if (e.length > 0) { + GCFEvent* full_event = 0; + char* event_buf = new char[sizeof(e) + e.length]; + full_event = (GCFEvent*)event_buf; + memcpy(event_buf, &e, sizeof(e)); + + // read the payload right behind the just memcopied basic event struct + if (recv(event_buf + sizeof(e), e.length) > 0) { + // dispatchs an event with just received params + status = dispatch(*full_event); + } + delete [] event_buf; + } + // dispatchs an event without params + else { + status = dispatch(e); + } + + if (status != GCFEvent::HANDLED) { + ASSERT(getTask()); + LOG_DEBUG(formatString ( + "'%s' for port '%s' in task '%s' not handled or an error occured", + getTask()->evtstr(e), getRealName().c_str(), + getTask()->getName().c_str())); + } + + return (status); } -const string& GCFRawPort::getRealName() const +// +// getRealName() +// +// Returns the name of the port. When the current port is a slave from +// a GCFPort the name of the GCFPort is used. +// When the name contains a colon we use makeServiceName to optain +// name is constructed equal to the code in PortItf::makeServiceName(). +// Note: +string GCFRawPort::getRealName() const { - return (isSlave() ? _pMaster->getName() : _name); +// return (isSlave() ? _pMaster->getName() : _name); + + GCFPort* thePort = (isSlave() ? _pMaster : (GCFPort*)(this)); + return (thePort->usesModernServiceName() ? + thePort->makeServiceName() : thePort->getName()); } + } // namespace TM } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/TM/src/PortImpl/GCF_DevicePort.cc b/MAC/GCF/TM/src/PortImpl/GCF_DevicePort.cc index 02d704e80470756f6afa7242c2427da1dce2f86f..8ebd38adc167adbc539d5d63ca3e4aaac39e16ad 100644 --- a/MAC/GCF/TM/src/PortImpl/GCF_DevicePort.cc +++ b/MAC/GCF/TM/src/PortImpl/GCF_DevicePort.cc @@ -27,7 +27,7 @@ #include <GTM_Defines.h> #include <GCF/TM/GCF_Task.h> #include <GCF/TM/GCF_Protocols.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> #include <errno.h> namespace LOFAR @@ -37,11 +37,11 @@ namespace LOFAR namespace TM { -GCFDevicePort::GCFDevicePort(GCFTask& task, - string name, - int protocol, - const string& deviceName, - bool transportRawData) +GCFDevicePort::GCFDevicePort(GCFTask& task, + const string& name, + int protocol, + const string& deviceName, + bool transportRawData) : GCFRawPort(task, name, SAP, protocol, transportRawData), _devNameIsSet((deviceName.length() > 0)), _pDevice(0), @@ -110,7 +110,7 @@ bool GCFDevicePort::open() { // retrieve the device name from the parameter set setDeviceName( - ParameterSet::instance()->getString( + ACC::APS::globalParameterSet()->getString( formatString( "mac.ns.%s.%s.deviceName", _pTask->getName().c_str(), diff --git a/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc b/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc index 4121d15f42ab54e5e2e3b87751a0b232b2b12456..75f123443fa92371e8247217bedde9ca2828d134 100644 --- a/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc +++ b/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc @@ -30,7 +30,7 @@ #include "GTM_ETHSocket.h" #include <GTM_Defines.h> #include <errno.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> namespace LOFAR { @@ -39,10 +39,10 @@ namespace LOFAR namespace TM { -GCFETHRawPort::GCFETHRawPort(GCFTask& task, - string name, - TPortType type, - bool transportRawData) : +GCFETHRawPort::GCFETHRawPort(GCFTask& task, + const string& name, + TPortType type, + bool transportRawData) : GCFRawPort(task, name, type, 0, transportRawData), _pSocket(0), _ethertype(0x0000) { @@ -97,7 +97,7 @@ bool GCFETHRawPort::open() PARAM_ETH_IFNAME, getTask()->getName().c_str(), getRealName().c_str()); - _ifname += ParameterSet::instance()->getString(ifNameParam); + _ifname += ACC::APS::globalParameterSet()->getString(ifNameParam); } catch (...) { @@ -114,7 +114,7 @@ bool GCFETHRawPort::open() PARAM_ETH_MACADDR, getTask()->getName().c_str(), getRealName().c_str()); - _destMacStr += ParameterSet::instance()->getString(destMacParam); + _destMacStr += ACC::APS::globalParameterSet()->getString(destMacParam); } catch (...) { @@ -131,7 +131,7 @@ bool GCFETHRawPort::open() PARAM_ETH_ETHERTYPE, getTask()->getName().c_str(), getRealName().c_str()); - _ethertype += ParameterSet::instance()->getInt(ethertypeParam); + _ethertype += ACC::APS::globalParameterSet()->getInt32(ethertypeParam); } catch (...) { diff --git a/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc b/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc index 3098a4b0f8c2656e651d408e25b6cc80b271a320..96521d1e05aeaa2f4fd742df535ead291c29b8df 100644 --- a/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc +++ b/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc @@ -25,45 +25,45 @@ #include <GCF/TM/GCF_TCPPort.h> #include <GCF/TM/GCF_Task.h> #include <GCF/TM/GCF_Protocols.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> #include "GTM_TCPServerSocket.h" #include <ServiceBroker/GTM_ServiceBroker.h> #include <ServiceBroker/GSB_Defines.h> #include <GTM_Defines.h> #include <errno.h> -namespace LOFAR -{ - namespace GCF - { - - using namespace SB; - - namespace TM - { +namespace LOFAR { + using namespace ACC::APS; + namespace GCF { + using namespace SB; + namespace TM { -GCFTCPPort::GCFTCPPort(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData) +// +// GCFTCPPort(task, servicename, type, protocol, raw) +// +GCFTCPPort::GCFTCPPort(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) : GCFRawPort(task, name, type, protocol, transportRawData), _pSocket(0), _addrIsSet(false), _portNumber(0), _broker(0) { - if (SPP == getType() || MSPP == getType()) - { - _pSocket = new GTMTCPServerSocket(*this, (MSPP == type)); - } - else if (SAP == getType()) - { - _pSocket = new GTMTCPSocket(*this); - } + if (SPP == getType() || MSPP == getType()) { + _pSocket = new GTMTCPServerSocket(*this, (MSPP == type)); + } + else if (SAP == getType()) { + _pSocket = new GTMTCPSocket(*this); + } } +// +// GCFTCPPorT() +// GCFTCPPort::GCFTCPPort() : GCFRawPort(), _pSocket(0), @@ -73,315 +73,317 @@ GCFTCPPort::GCFTCPPort() { } +// +// ~GCFTCPPort() +// GCFTCPPort::~GCFTCPPort() { - if (_pSocket) - { - delete _pSocket; - _pSocket = 0; - } - - if (_broker) - { - _broker->deletePort(*this); - GTMServiceBroker::release(); - _broker = 0; - } + if (_pSocket) { + delete _pSocket; + _pSocket = 0; + } + + if (_broker) { + _broker->deletePort(*this); + GTMServiceBroker::release(); + _broker = 0; + } } -void GCFTCPPort::init(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData) +// +// init (task, servicename, type, protocol, raw) +// +void GCFTCPPort::init(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) { _state = S_DISCONNECTED; GCFRawPort::init(task, name, type, protocol, transportRawData); _portNumber = 0; - _addrIsSet = false; - if (_pSocket) delete _pSocket; - _pSocket = 0; - _host = ""; + _host = ""; + _addrIsSet = false; + if (_pSocket) { + delete _pSocket; + _pSocket = 0; + } } +// +// try to open the socket +// Remember that this routine may be called many times before a socket is +// really open. +// bool GCFTCPPort::open() { - if (isConnected()) - { - LOG_ERROR(formatString ( - "Port %s already open.", - getRealName().c_str())); - return false; - } - else if (!_pSocket) - { - if (isSlave()) - { - LOG_ERROR(formatString ( - "Port %s not initialised.", - getRealName().c_str())); - return false; - } - else - { - if (SPP == getType() || MSPP == getType()) - { - _pSocket = new GTMTCPServerSocket(*this, (MSPP == getType())); - } - else if (SAP == getType()) - { - _pSocket = new GTMTCPSocket(*this); - } - } - } - - setState(S_CONNECTING); - if (SAP == getType()) - { - if (_host == "" || _portNumber == 0) - { - TPeerAddr fwaddr; - if (findAddr(fwaddr)) - { - setAddr(fwaddr); - } - else - { - if (!_addrIsSet) - { - LOG_ERROR(formatString ( - "No remote address info is set for port '%s' of task '%s'.", - getRealName().c_str(), _pTask->getName().c_str())); - LOG_INFO("See the last log of ParameterSet.cc file or use setAddr method."); - setState(S_DISCONNECTED); - return false; - } - } - string portNumParam = formatString(PARAM_TCP_PORTNR, - _addr.taskname.c_str(), - _addr.portname.c_str()); - if (ParameterSet::instance()->isDefined(portNumParam)) - { - _portNumber = ParameterSet::instance()->getInt(portNumParam); - string hostParam = formatString(PARAM_TCP_HOST, - _addr.taskname.c_str(), - _addr.portname.c_str()); - if (ParameterSet::instance()->isDefined(hostParam)) - { - _host = ParameterSet::instance()->getString(hostParam); - } - else - { - _host = "localhost"; - } - } - } - - if (_host != "" && _portNumber > 0) - { - serviceInfo(SB_NO_ERROR, _portNumber, _host); - } - else - { - string remoteServiceName = formatString("%s:%s", - _addr.taskname.c_str(), - _addr.portname.c_str()); - if (!_broker) - { - _broker = GTMServiceBroker::instance(); - } - ASSERT(_broker); - _broker->getServiceinfo(*this, remoteServiceName); - } - } - else - { - string portNumParam = formatString(PARAM_TCP_PORTNR, - getTask()->getName().c_str(), - getRealName().c_str()); - if (ParameterSet::instance()->isDefined(portNumParam)) - { - _portNumber = ParameterSet::instance()->getInt(portNumParam); - } - if (_portNumber > 0) - { - serviceRegistered(SB_NO_ERROR, _portNumber); - } - else - { - _broker = GTMServiceBroker::instance(); - ASSERT(_broker); - _broker->registerService(*this); - } - } - return true; + // already connect? + if (isConnected()) { + LOG_ERROR(formatString("Port %s already open.", + makeServiceName().c_str())); + return (false); + } + + // allocate a TCP socket when not done before. + if (!_pSocket) { + if (isSlave()) { + LOG_ERROR(formatString ("Port %s not initialised.", + makeServiceName().c_str())); + return (false); + } + + if ((getType() == SPP) || (getType() == MSPP)) { + _pSocket = new GTMTCPServerSocket(*this, (MSPP == getType())); + } + else { + ASSERTSTR (SAP == getType(), "Unknown TPCsocket type " << getType()); + _pSocket = new GTMTCPSocket(*this); + } + } + + setState(S_CONNECTING); + + if (getType() == SAP) { // client socket? + if (_host != "" && _portNumber != 0) { // dest. overruled by user? + // Try to 'open' en 'connect' to port + serviceInfo(SB_NO_ERROR, _portNumber, _host); + return (true); + } + + string remoteServiceName; + // If service name is not set yet try to resolve it. + if (usesModernServiceName()) { + remoteServiceName = makeServiceName(); + } + else { + if (!_addrIsSet) { + TPeerAddr fwaddr; + // try mac.top.<taskname>.<name>.remoteservice in gblPS + if (findAddr(fwaddr)) { + setAddr(fwaddr); + remoteServiceName = formatString("%s:%s", + fwaddr.taskname.c_str(), fwaddr.portname.c_str()); + } + else { + // No information available to connect. + setState(S_DISCONNECTED); + ASSERTSTR(false, "No remote address info for port '" << + getRealName() << "' of task " << + _pTask->getName()); + } + } + } + + // Service name is set, use it to resolve host+port and connect. + if (!_broker) { + _broker = GTMServiceBroker::instance(); + } + ASSERT(_broker); + _broker->getServiceinfo(*this, remoteServiceName); + // a (dis)connect event will be scheduled + return (true); + } + + // porttype = MSPP or SPP + // portnumber overruled by user? try mac.ns.<taskname>.<realname>.port + string portNumParam = formatString(PARAM_TCP_PORTNR, + getTask()->getName().c_str(), getRealName().c_str()); + if (ACC::APS::globalParameterSet()->isDefined(portNumParam)) { + _portNumber = ACC::APS::globalParameterSet()->getInt32(portNumParam); + } + if (_portNumber > 0) { // portnumber hard set by user. + serviceRegistered(SB_NO_ERROR, _portNumber); // 'hard' open port + // a (dis)connect event will be scheduled + // Note: service is NOT registered at service broker!!! + } + else { // portnumber not overruled by user so ask SB for a portnumber + _broker = GTMServiceBroker::instance(); + ASSERT(_broker); + _broker->registerService(*this); + // a (dis)connect event will be scheduled + } + + return (true); } + +// +// serviceRegistered(resultToReturn, portNr) +// +// Log what port we use and try to open and connect to that port. +// Note: Is also called by the GTM_ServiceBroker +// void GCFTCPPort::serviceRegistered(unsigned int result, unsigned int portNumber) { - ASSERT(MSPP == getType() || SPP == getType()); - if (result == SB_NO_ERROR) - { - LOG_DEBUG(formatString ( - "(M)SPP port '%s' in task '%s' listens on portnumber %d.", - getRealName().c_str(), - _pTask->getName().c_str(), - portNumber)); - _portNumber = portNumber; - if (!_pSocket->open(portNumber)) - { - schedule_disconnected(); - } - else if (MSPP == getType()) - { - schedule_connected(); - } - } - else - { - schedule_disconnected(); - } + ASSERT(MSPP == getType() || SPP == getType()); + if (result != SB_NO_ERROR) { + schedule_disconnected(); + return; + } + + LOG_DEBUG(formatString ( + "(M)SPP port '%s' in task '%s' listens on portnumber %d.", + getRealName().c_str(), _pTask->getName().c_str(), + portNumber)); + _portNumber = portNumber; + if (!_pSocket->open(portNumber)) { + schedule_disconnected(); + return; + } + + if (getType() == MSPP) { + schedule_connected(); + } } + +// +// serviceInfo (result, portNumber) +// +// Ask servicebroker for a portnumber and try to open the port(listener) +// +// Note: Is also called by the GTM_ServiceBroker void GCFTCPPort::serviceInfo(unsigned int result, unsigned int portNumber, const string& host) { - ASSERT(SAP == getType()); - if (result == SB_UNKNOWN_SERVICE) - { - LOG_DEBUG(formatString ( - "Cannot connect the local SAP [%s:%s] to remote (M)SPP [%s:%s]. Try again!!!", - _pTask->getName().c_str(), - getRealName().c_str(), - _addr.taskname.c_str(), - _addr.portname.c_str())); - - schedule_disconnected(); - } - else if (result == SB_NO_ERROR) - { - _portNumber = portNumber; - _host = host; - LOG_DEBUG(formatString ( - "Can now connect the local SAP [%s:%s] to remote (M)SPP [%s:%s@%s:%d].", - _pTask->getName().c_str(), - getRealName().c_str(), - _addr.taskname.c_str(), - _addr.portname.c_str(), - host.c_str(), - portNumber)); - - if (_pSocket->open(portNumber)) - { - if (_pSocket->connect(portNumber, host)) - { - schedule_connected(); - } - else - { - schedule_disconnected(); - } - } - else - { - schedule_disconnected(); - } - } + ASSERT(SAP == getType()); + if (result == SB_UNKNOWN_SERVICE) { + LOG_DEBUG(formatString ("Cannot connect the local SAP [%s] " + "to remote (M)SPP [%s:%s]. Try again!!!", + makeServiceName().c_str(), + _addr.taskname.c_str(), _addr.portname.c_str())); + + schedule_disconnected(); + return; + } + + if (result == SB_NO_ERROR) { + _portNumber = portNumber; + _host = host; + LOG_DEBUG(formatString ("Can now connect the local SAP [%s] " + "to remote (M)SPP [%s:%s@%s:%d].", + makeServiceName().c_str(), + _addr.taskname.c_str(), _addr.portname.c_str(), + host.c_str(), portNumber)); + + if (_pSocket->open(portNumber) && _pSocket->connect(portNumber, host)) { + schedule_connected(); + return; + } + + schedule_disconnected(); + } } +// Note: Is also called by the GTM_ServiceBroker void GCFTCPPort::serviceGone() { - _host = ""; - _portNumber = 0; + _host = ""; + _portNumber = 0; } +// +// send(event) +// ssize_t GCFTCPPort::send(GCFEvent& e) { - ssize_t written = 0; + ssize_t written = 0; - ASSERT(_pSocket); + ASSERT(_pSocket); + + if (!isConnected()) { + LOG_ERROR(formatString ( + "Port '%s' on task '%s' not connected! Event not sent!", + getRealName().c_str(), getTask()->getName().c_str())); + return 0; + } + + if (MSPP == getType()) { + return 0; // no messages can be send by this type of port + } + + unsigned int packsize; + void* buf = e.pack(packsize); + + LOG_TRACE_STAT(formatString ( + "Sending event '%s' for task '%s' on port '%s'", + getTask()->evtstr(e), getTask()->getName().c_str(), + getRealName().c_str())); - if (!isConnected()) - { - LOG_ERROR(formatString ( - "Port '%s' on task '%s' not connected! Event not sent!", - getRealName().c_str(), - getTask()->getName().c_str())); - return 0; - } - - if (MSPP == getType()) - return 0; // no messages can be send by this type of port - - - unsigned int packsize; - void* buf = e.pack(packsize); - - LOG_DEBUG(formatString ( - "Sending event '%s' for task '%s' on port '%s'", - getTask()->evtstr(e), - getTask()->getName().c_str(), - getRealName().c_str())); - - if ((written = _pSocket->send(buf, packsize)) != (ssize_t) packsize) - { - setState(S_DISCONNECTING); - schedule_disconnected(); - - written = 0; - } - - return written; + if ((written = _pSocket->send(buf, packsize)) != (ssize_t) packsize) { + setState(S_DISCONNECTING); + schedule_disconnected(); + + written = 0; + } + + return (written); } + +// +// recv(buf, count) +// ssize_t GCFTCPPort::recv(void* buf, size_t count) { ASSERT(_pSocket); return _pSocket->recv(buf, count); } +// +// close() +// bool GCFTCPPort::close() { - setState(S_CLOSING); - _pSocket->close(); - schedule_close(); + setState(S_CLOSING); + _pSocket->close(); + schedule_close(); - // return success when port is still connected - // scheduled close will only occur later - return isConnected(); + // return success when port is still connected + // scheduled close will only occur later + return isConnected(); } +// +// setAddr(addr) +// void GCFTCPPort::setAddr(const TPeerAddr& addr) { - if (_addr.taskname != addr.taskname || _addr.portname != addr.portname) - { - _host = ""; - _portNumber = 0; - } - _addr = addr; - if (_addr.taskname != "" && _addr.portname != "") - { - _addrIsSet = true; - } + LOG_DEBUG_STR("set service at " << addr.taskname << ":" << addr.portname); + + // Is new address different from current address? + if (_addr.taskname != addr.taskname || _addr.portname != addr.portname) { + _host = ""; // clear current settings + _portNumber = 0; + } + _addr = addr; + _addrIsSet = ((_addr.taskname != "") && (_addr.portname != "")); + _deviceNameMask = formatString("%s:%s", _addr.taskname.c_str(), + _addr.portname.c_str()); } +// +// accept(port) +// bool GCFTCPPort::accept(GCFTCPPort& port) { - bool result(false); - if (MSPP == getType() && SPP == port.getType()) - { - GTMTCPServerSocket* pProvider = (GTMTCPServerSocket*)_pSocket; - if (port._pSocket == 0) - { - port._pSocket = new GTMTCPSocket(port); - } - if (pProvider->accept(*port._pSocket)) - { - setState(S_CONNECTING); - port.schedule_connected(); - result = true; - } - } - return result; + bool result(false); + + // TODO: MSPP is check against getType and SPP against PORT.getType() !!!! + if (getType() != MSPP || port.getType() != SPP) { + return (false); + } + + GTMTCPServerSocket* pProvider = (GTMTCPServerSocket*)_pSocket; + if (port._pSocket == 0) { + port._pSocket = new GTMTCPSocket(port); + } + + if (pProvider->accept(*port._pSocket)) { + setState(S_CONNECTING); + port.schedule_connected(); + result = true; + } + return result; } } // namespace TM } // namespace GCF diff --git a/MAC/GCF/TM/src/PortImpl/GCF_TimerPort.cc b/MAC/GCF/TM/src/PortImpl/GCF_TimerPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..21f859dbd3fc70fff463968cde9f6662af4ed6fc --- /dev/null +++ b/MAC/GCF/TM/src/PortImpl/GCF_TimerPort.cc @@ -0,0 +1,121 @@ +//# GCF_TimerPort.cc: Raw connection to a remote process +//# +//# 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$ + +#include <lofar_config.h> + +#include <GCF/TM/GCF_TimerPort.h> +#include <GCF/TM/GCF_PortInterface.h> +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Protocols.h> +#include <GTM_Defines.h> +#include <Timer/GTM_TimerHandler.h> + +namespace LOFAR { + namespace GCF { + namespace TM { + +// +// GCFTimerPort() +// +GCFTimerPort::GCFTimerPort(GCFTask& aTask, + const string& aName) : + GCFRawPort(&aTask, aName, SAP, 0, false) +{ + _pTimerHandler = GTMTimerHandler::instance(); + ASSERT(_pTimerHandler); +} + +// +// ~GCFTimerPort() +// +GCFTimerPort::~GCFTimerPort() +{ + cancelAllTimers(); + ASSERT(_pTimerHandler); + GTMTimerHandler::release(); + _pTimerHandler = 0; +} + +// +// dispatch(event) +// +GCFEvent::TResult GCFTimerPort::dispatch(GCFEvent& event) +{ + ASSERT(_pTask); + return (_pTask->dispatch(event, *this)); +} + +// +// settimer(sec, usec, itvsec, itvusec, arg) +// +long GCFTimerPort::setTimer(long delay_sec, long delay_usec, + long interval_sec, long interval_usec, + void* arg) +{ + ASSERT(_pTimerHandler); + uint64 delay(delay_sec); + uint64 interval(interval_sec); + delay *= 1000000; + interval *= 1000000; + delay += (uint64) delay_usec; + interval += (uint64) interval_usec; + + return (_pTimerHandler->setTimer(*this, delay, interval, arg)); +} + +// +// setTimer(sec, itvsec, arg) +// +long GCFTimerPort::setTimer(double delay_seconds, + double interval_seconds, + void* arg) +{ + ASSERT(_pTimerHandler); + + return (_pTimerHandler->setTimer(*this, + (uint64) (delay_seconds * 1000000.0), + (uint64) (interval_seconds * 1000000.0), + arg)); +} + +// +// cancelTimer(timerid, arg) +// +int GCFTimerPort::cancelTimer(long timerid, void **arg) +{ + ASSERT(_pTimerHandler); + return _pTimerHandler->cancelTimer(timerid, arg); +} + +// +// cancelAllTimers() +// +int GCFTimerPort::cancelAllTimers() +{ + ASSERT(_pTimerHandler); + return _pTimerHandler->cancelAllTimers(*this); +} + + + } // namespace TM + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc b/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc index a4d19d876bd369ab40f35a0a91200222b717acdf..7d448cd76082a606324bda199688d4b0c5b44233 100644 --- a/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc +++ b/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc @@ -32,12 +32,9 @@ #include <fcntl.h> #include <errno.h> -namespace LOFAR -{ - namespace GCF - { - namespace TM - { +namespace LOFAR { + namespace GCF { + namespace TM { GTMTCPServerSocket::GTMTCPServerSocket(GCFTCPPort& port, bool isProvider) : GTMTCPSocket(port), @@ -53,88 +50,70 @@ GTMTCPServerSocket::~GTMTCPServerSocket() bool GTMTCPServerSocket::open(unsigned int portNumber) { - bool result(false); - if (_fd == -1) - { - struct sockaddr_in address; - int addrLen; - int socketFD = ::socket(AF_INET, SOCK_STREAM, 0); - if (socketFD > -1) - { - unsigned int val = 1; - struct linger lin = { 1,1 }; - - if (::setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val)) < 0) - { - LOG_WARN(formatString ( - "Error on setting socket options SO_REUSEADDR: %s", - strerror(errno))); - return false; - } - - if (::setsockopt(socketFD, SOL_SOCKET, SO_LINGER, (const char*)&lin, sizeof(lin)) < 0) - { - LOG_WARN(formatString ( - "Error on setting socket options SO_LINGER: %s", - strerror(errno))); - return false; - } - - address.sin_family = AF_INET; - address.sin_addr.s_addr = htonl(INADDR_ANY); - address.sin_port = htons(portNumber); - addrLen = sizeof(address); - if (bind(socketFD, (struct sockaddr*)&address, addrLen) > -1) - { - if (listen(socketFD, 5) > -1) - { - setFD(socketFD); - result = (fcntl(socketFD, F_SETFL, FNDELAY) == 0); - } - else - { - LOG_WARN(formatString ( - "::listen, error: %s", - strerror(errno))); - } - } - else - { - LOG_WARN(formatString ( - "::bind, error: %s", - strerror(errno))); - } - if (!result) - close(); - } - else - { - LOG_WARN(formatString ( - "::socket, error: %s", - strerror(errno))); - } - } - else - { - if (_pDataSocket != 0) - { - _pDataSocket->close(); - result = true; - } - } - - return result; + if (_fd != -1) { + if (_pDataSocket != 0) { + _pDataSocket->close(); + return(true); + } + return (false); + } + + struct sockaddr_in address; + int addrLen; + int socketFD = ::socket(AF_INET, SOCK_STREAM, 0); + if (socketFD == -1) { + LOG_WARN(formatString ( "::socket, error: %s", strerror(errno))); + return (false); + } + unsigned int val = 1; + struct linger lin = { 1,1 }; + + if (::setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val)) < 0) { + LOG_WARN(formatString ( + "Error on setting socket options SO_REUSEADDR: %s", + strerror(errno))); + return false; + } + + if (::setsockopt(socketFD, SOL_SOCKET, SO_LINGER, (const char*)&lin, sizeof(lin)) < 0) { + LOG_WARN(formatString ( + "Error on setting socket options SO_LINGER: %s", + strerror(errno))); + return false; + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(INADDR_ANY); + address.sin_port = htons(portNumber); + addrLen = sizeof(address); + if (bind(socketFD, (struct sockaddr*)&address, addrLen) == -1) { + LOG_WARN(formatString ( "::bind, error: %s", strerror(errno))); + close(); + return (false); + } + + if (listen(socketFD, 5) == -1) { + LOG_WARN(formatString ( "::listen, error: %s", strerror(errno))); + close(); + return (false); + } + + setFD(socketFD); + if (fcntl(socketFD, F_SETFL, FNDELAY) != 0) { + close(); + return (false); + } + + return (true); } void GTMTCPServerSocket::workProc() { - if (_isProvider) - { + if (_isProvider) { GCFEvent acceptReqEvent(F_ACCEPT_REQ); dispatch(acceptReqEvent); } - else - { + else { GCFTCPPort* pPort = (GCFTCPPort*)(&_port); ASSERT(_pDataSocket == 0); @@ -147,16 +126,12 @@ void GTMTCPServerSocket::workProc() (struct sockaddr*) &clientAddress, &clAddrLen)); - if (_pDataSocket->getFD() >= 0) - { + if (_pDataSocket->getFD() >= 0) { GCFEvent connectedEvent(F_CONNECTED); dispatch(connectedEvent); } - else - { - LOG_WARN(formatString ( - "::accept, error: %s", - strerror(errno))); + else { + LOG_WARN(formatString ( "::accept, error: %s", strerror(errno))); } // because we only accept one connection (SPP), we don't need to listen with @@ -168,8 +143,7 @@ void GTMTCPServerSocket::workProc() bool GTMTCPServerSocket::accept(GTMFile& newSocket) { bool result(false); - if (_isProvider && _pDataSocket == 0) - { + if (_isProvider && _pDataSocket == 0) { struct sockaddr_in clientAddress; socklen_t clAddrLen = sizeof(clientAddress); int newSocketFD; @@ -178,8 +152,7 @@ bool GTMTCPServerSocket::accept(GTMFile& newSocket) &clAddrLen); result = (newSocket.setFD(newSocketFD) > 0); - if (!result) - { + if (!result) { LOG_WARN(formatString ( "::accept, error: %s", strerror(errno))); @@ -193,8 +166,7 @@ bool GTMTCPServerSocket::close() { bool result(true); - if (!_isProvider && _pDataSocket != 0) - { + if (!_isProvider && _pDataSocket != 0) { result = _pDataSocket->close(); delete _pDataSocket; _pDataSocket = 0; diff --git a/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc b/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc index 9e3eb4eb13ad0ccb326ca5a0f9cc17f2c2351a43..ae61e98b9efe5cfe6333b05ee56496d83ee86f8b 100644 --- a/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc +++ b/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc @@ -54,33 +54,27 @@ GTMTCPSocket::~GTMTCPSocket() ssize_t GTMTCPSocket::send(void* buf, size_t count) { - if (_fd > -1) - { + if (_fd > -1) { ssize_t countLeft(count); ssize_t written(0); - do - { + do { written = ::write(_fd, ((char*)buf) + (count - countLeft), countLeft); - if (written == -1) - { - if (errno != EINTR) - { + if (written == -1) { + if (errno != EINTR) { LOG_WARN(LOFAR::formatString ( "send, error: %s", strerror(errno))); return -1; } } - else - { + else { countLeft -= written; } } while (countLeft > 0); return count; } - else - { + else { LOG_WARN("send, error: Socket not opend"); return -1; } @@ -88,33 +82,27 @@ ssize_t GTMTCPSocket::send(void* buf, size_t count) ssize_t GTMTCPSocket::recv(void* buf, size_t count) { - if (_fd > -1) - { + if (_fd > -1) { ssize_t countLeft(count); ssize_t received(0); - do - { + do { received = ::read(_fd, ((char*)buf) + (count - countLeft), countLeft); - if (received == -1) - { - if (errno != EINTR) - { + if (received == -1) { + if (errno != EINTR) { LOG_WARN(formatString ( "recv, error: %s", strerror(errno))); return -1; } } - else - { + else { countLeft -= received; } } while (countLeft > 0); return count; } - else - { + else { LOG_WARN("recv, error: Socket not opend"); return -1; } @@ -124,11 +112,8 @@ bool GTMTCPSocket::open(unsigned int /*portNumber*/) { ASSERT(_fd == -1); _fd = ::socket(AF_INET, SOCK_STREAM, 0); - if (_fd < 0) - { - LOG_WARN(formatString ( - "::socket, error: %s", - strerror(errno))); + if (_fd < 0) { + LOG_WARN(formatString ( "::socket, error: %s", strerror(errno))); close(); } return (_fd > -1); @@ -137,28 +122,21 @@ bool GTMTCPSocket::open(unsigned int /*portNumber*/) bool GTMTCPSocket::connect(unsigned int portNumber, const string& host) { bool result(false); - if (_fd >= -1) - { + if (_fd >= -1) { struct sockaddr_in serverAddr; struct hostent *hostinfo; hostinfo = gethostbyname(host.c_str()); serverAddr.sin_family = AF_INET; serverAddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; serverAddr.sin_port = htons(portNumber); - result = (::connect(_fd, - (struct sockaddr *)&serverAddr, - sizeof(struct sockaddr_in)) - == 0); - if (result) - { + result = (::connect(_fd, (struct sockaddr *)&serverAddr, + sizeof(struct sockaddr_in)) == 0); + if (result) { ASSERT(_pHandler); _pHandler->registerFile(*this); } - else - { - LOG_WARN(formatString ( - "connect, error: %s", - strerror(errno))); + else { + LOG_WARN(formatString ( "connect, error: %s", strerror(errno))); close(); } } diff --git a/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.cc b/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.cc index d805c67828af71808a75774c82452e02a77a1738..360171ca462c42e9939ca8a95213ebb52ccb7ff0 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.cc +++ b/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.cc @@ -22,361 +22,320 @@ #include <lofar_config.h> -#include "GSB_Controller.h" +#include <APS/ParameterSet.h> +#include <GCF/Utils.h> +#include <GCF/GCF_ServiceInfo.h> #include <../SB_Protocol.ph> -#include <GCF/ParameterSet.h> #include <GSB_Defines.h> +#include "GSB_Controller.h" -namespace LOFAR -{ - namespace GCF - { +namespace LOFAR { + namespace GCF { using namespace TM; - namespace SB - { + namespace SB { -static string sSBTaskName("GCF-SB"); +static string sSBTaskName("ServiceBrokerTask"); +// +// xxx +// GSBController::GSBController() : - GCFTask((State)&GSBController::initial, sSBTaskName), - _counter(0) + GCFTask((State)&GSBController::initial, sSBTaskName) { - // register the protocol for debugging purposes - registerProtocol(SB_PROTOCOL, SB_PROTOCOL_signalnames); + // register the protocol for debugging purposes + registerProtocol(SB_PROTOCOL, SB_PROTOCOL_signalnames); + + // allocate the listener port + itsListener.init(*this, MAC_SVCMASK_SERVICEBROKER, + GCFPortInterface::MSPP, SB_PROTOCOL); - // initialize the port - _brokerProvider.init(*this, "provider", GCFPortInterface::MSPP, SB_PROTOCOL); - readRanges(); + // read the port range I may use + readRanges(); } +// +// xxx +// GSBController::~GSBController() { - cleanupGarbage(); - LOG_INFO("Deleting ServiceBroker"); + LOG_DEBUG("Deleting ServiceBroker"); } -GCFEvent::TResult GSBController::initial(GCFEvent& e, GCFPortInterface& p) +// +// initial(event, port) +// +GCFEvent::TResult GSBController::initial(GCFEvent& event, GCFPortInterface& port) { - GCFEvent::TResult status = GCFEvent::HANDLED; + GCFEvent::TResult status = GCFEvent::HANDLED; - switch (e.signal) - { - case F_INIT: - break; + switch (event.signal) { + case F_INIT: + break; - case F_ENTRY: - case F_TIMER: - _brokerProvider.open(); - break; + case F_ENTRY: + case F_TIMER: + itsListener.open(); // Open Listener port + break; - case F_CONNECTED: - TRAN(GSBController::operational); - break; + case F_CONNECTED: + // Once listener is opened I am operational + TRAN(GSBController::operational); + break; - case F_DISCONNECTED: - if (&p == &_brokerProvider) - _brokerProvider.setTimer(1.0); // try again after 1 second - break; + case F_DISCONNECTED: + if (&port == &itsListener) + itsListener.setTimer(1.0); // try again after 1 second + break; - default: - status = GCFEvent::NOT_HANDLED; - break; - } + default: + status = GCFEvent::NOT_HANDLED; + break; + } - return status; + return (status); } -GCFEvent::TResult GSBController::operational(GCFEvent& e, GCFPortInterface& p) +// +// operational(event, port) +// +GCFEvent::TResult GSBController::operational(GCFEvent& event, GCFPortInterface& port) { - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (e.signal) - { - case F_CONNECTED: - cleanupGarbage(); - _brokerClients.push_back(&p); - break; - - case F_ACCEPT_REQ: - acceptConnectRequest(); - break; - - case F_DISCONNECTED: - if (&p != &_brokerProvider) p.close(); - // else //TODO: find out this can realy happend - break; - - case F_CLOSED: - clientGone(p); - break; - - case SB_REGISTER_SERVICE: - { - SBRegisterServiceEvent request(e); - SBServiceRegisteredEvent response; - response.seqnr = request.seqnr; - if (findService(request.servicename)) - { - LOG_ERROR(formatString( - "Service %s already exist", - request.servicename.c_str())); - response.result = SB_SERVICE_ALREADY_EXIST; - } - else - { - TServiceInfo serviceInfo; - serviceInfo.portNumber = claimPortNumber(request.host); - if (serviceInfo.portNumber > 0) - { - LOG_INFO(formatString( - "Service %s registered with portnumber %d", - request.servicename.c_str(), - serviceInfo.portNumber)); - serviceInfo.host = request.host; - serviceInfo.pPortToOwner = &p; - _services[request.servicename] = serviceInfo; - - response.result = SB_NO_ERROR; - response.portnumber = serviceInfo.portNumber; - } - else - { - LOG_ERROR(formatString( - "All available port numbers are claimed (%s)", - request.servicename.c_str())); - response.result = SB_NO_FREE_PORTNR; - } - } - p.send(response); - break; - } - case SB_UNREGISTER_SERVICE: - { - SBUnregisterServiceEvent request(e); - TServiceInfo* pServiceInfo = findService(request.servicename); - if (pServiceInfo) - { - LOG_INFO(formatString( - "Service %s unregistered", - request.servicename.c_str())); - freePort(request.servicename, pServiceInfo); - _services.erase(request.servicename); - } - else - { - LOG_ERROR(formatString( - "Unknown service: %s", - request.servicename.c_str())); - } - break; - } - case SB_GET_SERVICEINFO: - { - SBGetServiceinfoEvent request(e); - SBServiceInfoEvent response; - response.seqnr = request.seqnr; - TServiceInfo* pServiceInfo = findService(request.servicename); - if (pServiceInfo) - { - LOG_INFO(formatString( - "Service %s requested on %s:%d", - request.servicename.c_str(), - pServiceInfo->host.c_str(), - pServiceInfo->portNumber)); - response.host = pServiceInfo->host; - response.portnumber = pServiceInfo->portNumber; - response.result = SB_NO_ERROR; - } - else - { - LOG_ERROR(formatString( - "Unknown service: %s", - request.servicename.c_str())); - response.result = SB_UNKNOWN_SERVICE; - } - p.send(response); - break; - } - default: - status = GCFEvent::NOT_HANDLED; - break; - } - - return status; + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_CONNECTED: + break; + + case F_ACCEPT_REQ: + acceptConnectRequest(); + break; + + case F_DISCONNECTED: + if (&port != &itsListener) { + port.close(); + } + // else //TODO: find out this can realy happend + break; + + case F_CLOSED: + releasePort(&port); + break; + + case SB_REGISTER_SERVICE: { + SBRegisterServiceEvent request(event); + SBServiceRegisteredEvent response; + response.seqnr = request.seqnr; + + // Is Service already registered? + if (findService(request.servicename)) { + LOG_ERROR(formatString("Service %s already exist", + request.servicename.c_str())); + response.result = SB_SERVICE_ALREADY_EXIST; + } + else { + uint16 portNr = claimPortNumber(request.servicename, &port); + if (portNr > 0) { + response.result = SB_NO_ERROR; + response.portnumber = portNr; + } + else { + LOG_ERROR(formatString ("All available port numbers are claimed (%s)", + request.servicename.c_str())); + response.result = SB_NO_FREE_PORTNR; + } + } + port.send(response); + break; + } + + case SB_UNREGISTER_SERVICE: { + SBUnregisterServiceEvent request(event); + releaseService(request.servicename); + break; + } + + case SB_GET_SERVICEINFO: { + SBGetServiceinfoEvent request(event); + SBServiceInfoEvent response; + response.seqnr = request.seqnr; + + uint16 portNr = findService(request.servicename); + if (portNr) { + LOG_INFO(formatString ("Serviceinfo for %s is %d", + request.servicename.c_str(), portNr)); + response.portnumber = portNr; + response.hostname = Common::myHostname(); + response.result = SB_NO_ERROR; + } + else { + LOG_ERROR(formatString ("Unknown service: %s", + request.servicename.c_str())); + response.result = SB_UNKNOWN_SERVICE; + } + port.send(response); + break; + } + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; } +// +// acceptConnectRequest +// void GSBController::acceptConnectRequest() { - GTMSBTCPPort* pNewSBClientPort = new GTMSBTCPPort(); - ASSERT(pNewSBClientPort); - pNewSBClientPort->init(*this, "server", GCFPortInterface::SPP, SB_PROTOCOL); - _brokerProvider.accept(*pNewSBClientPort); - LOG_INFO("A new SB client tries to connect. Accept!!!"); -} + LOG_DEBUG ("A new SB client tries to connect. Accept!!!"); -void GSBController::clientGone(GCFPortInterface& p) -{ - // first step of what must be done before the closed port can be deleted too - LOG_INFO("A SB client is gone, so start the closing sequence!"); - - TServiceInfo* pServiceInfo; - list<string> servicesGarbage; - // search for all services registered via the closed port - for (TServices::iterator sIter = _services.begin(); - sIter != _services.end(); ++sIter) - { - pServiceInfo = &sIter->second; - if (pServiceInfo->pPortToOwner == &p) - { - servicesGarbage.push_back(sIter->first); - // the involved and claimed portnumbers must be freed - freePort(sIter->first, pServiceInfo); - } - } - - // delete found services - for (list<string>::iterator iter = servicesGarbage.begin(); - iter != servicesGarbage.end(); ++iter) - { - _services.erase(*iter); - } - - // move closed port to garbage list - _brokerClients.remove(&p); - _brokerClientsGarbage.push_back(&p); - LOG_INFO("Closing sequence finished!"); -} + GTMSBTCPPort* pNewSBClientPort = new GTMSBTCPPort(); + ASSERT(pNewSBClientPort); -void GSBController::freePort(const string& servicename, TServiceInfo* pServiceInfo) -{ - SBServiceGoneEvent indication; - - TPortStates* pPortStates = findHost(pServiceInfo->host); - if (pPortStates) - { - // 1: mark port as not in use - (*pPortStates)[pServiceInfo->portNumber] = false; - LOG_INFO(formatString( - "Portnumber %d freed for use on host '%s'.", - pServiceInfo->portNumber, - pServiceInfo->host.c_str())); - - // 2: send to each service client the indication that the service is gone - GCFPortInterface* pPort; - indication.servicename = servicename; - - for (list<GCFPortInterface*>::iterator pIter = _brokerClients.begin(); - pIter != _brokerClients.end(); ++pIter) - { - pPort = (*pIter); - if (pPort->isConnected()) - { - pPort->send(indication); - } - } - } + pNewSBClientPort->init(*this, "newClient", GCFPortInterface::SPP, SB_PROTOCOL); + itsListener.accept(*pNewSBClientPort); } -void GSBController::cleanupGarbage() +// +// readRanges +// +void GSBController::readRanges() { - GCFPortInterface* pPort; - for (list<GCFPortInterface*>::iterator iter = _brokerClientsGarbage.begin(); - iter != _brokerClientsGarbage.end(); ++iter) - { - pPort = *iter; - delete pPort; - } - _brokerClientsGarbage.clear(); + ASSERTSTR (ACC::APS::globalParameterSet()->isDefined("firstPortNumber") && + ACC::APS::globalParameterSet()->isDefined("lastPortNumber"), + "Ranges not specified in ParameterSet"); + + itsLowerLimit = ACC::APS::globalParameterSet()->getUint16("firstPortNumber"); + itsUpperLimit = ACC::APS::globalParameterSet()->getUint16("lastPortNumber"); + + ASSERTSTR(itsLowerLimit < itsUpperLimit, "Invalid portnumber range specified"); + ASSERTSTR(itsLowerLimit > 1023, "Portnumbers below 1024 may not be used"); + + itsNrPorts = itsUpperLimit - itsLowerLimit; + ASSERTSTR(itsNrPorts < 1000, + "Range too large, broker can manage only 1000 ports"); + + itsServiceList = vector<TServiceInfo> (itsNrPorts); + for (uint32 idx = 0; idx < itsNrPorts; idx++) { + itsServiceList[idx].portNumber = 0; + itsServiceList[idx].serviceName = ""; + itsServiceList[idx].ownerPort = 0; + } + + itsNrFreePorts = itsNrPorts; + + LOG_INFO (formatString("Managing portnumbers %d till %d (%d)", + itsLowerLimit, itsUpperLimit, itsNrPorts)); } -void GSBController::readRanges() +// +// claimPortNumber(serviceName, port) +// +uint16 GSBController::claimPortNumber(const string& aServiceName, + GCFPortInterface* aPort) { - ParameterSet rangeSet = ParameterSet::instance()->makeSubset("mac.gcf.sb.range"); - unsigned short rangeNr(1); - unsigned int firstValue(0); - unsigned int lastValue(0); - string host; - - string hostParam = formatString("%d.host", rangeNr); - string firstPortNumberParam; - string lastPortNumberParam; - while (rangeSet.isDefined(hostParam)) - { - firstPortNumberParam = formatString("%d.firstPortNumber", rangeNr); - lastPortNumberParam = formatString("%d.lastPortNumber", rangeNr); - host = rangeSet.getString(hostParam); - - try - { - firstValue = rangeSet.getInt(firstPortNumberParam); - } - catch (...) - { - LOG_FATAL(formatString ( - "No firstPortNumbers defined for range %d in ServiceBroker.conf file.", - rangeNr)); - exit(0); - } - - try - { - lastValue = rangeSet.getInt(lastPortNumberParam); - } - catch (...) - { - // if only firstValue is set than one value should be add to the available list - lastValue = firstValue; - } - - // swap values if first is higher then lastValue - if (firstValue > lastValue) - { - unsigned int tmpValue = lastValue; - lastValue = firstValue; - firstValue = tmpValue; - } - - TPortStates* pPortStates = &_availableHosts[host]; - for (unsigned int i = firstValue; i <= lastValue; i++) - { - (*pPortStates)[i] = false; - } - rangeNr++; - hostParam = formatString("%d.host", rangeNr); - } + int32 idx = 0; + + if (!itsNrFreePorts) { // must have room. + return (0); + } + + while (idx < itsNrPorts) { // scan whole array + if (itsServiceList[idx].portNumber == 0) { + itsServiceList[idx].portNumber = itsLowerLimit + idx; + itsServiceList[idx].serviceName = aServiceName; + itsServiceList[idx].ownerPort = aPort; + itsNrFreePorts--; + LOG_INFO(formatString ("Portnumber %d assigned to '%s'.", + itsServiceList[idx].portNumber, aServiceName.c_str())); + LOG_INFO_STR ("Managing " << itsNrPorts - itsNrFreePorts << " ports now"); + return (itsServiceList[idx].portNumber); + } + idx++; + } + + ASSERTSTR (false, "Major programming error in 'claimPortNumber'!"); } -unsigned int GSBController::claimPortNumber(const string& host) +// +// releaseService(servicename) +// +void GSBController::releaseService(const string& aServiceName) { - TPortStates* pPortStates = &_availableHosts[host]; - for (TPortStates::iterator portIter = pPortStates->begin(); - portIter != pPortStates->end(); ++portIter) - { - if (!portIter->second) - { - portIter->second = true; // portNumber is now in use - LOG_INFO(formatString( - "Portnumber %d claimed on host '%s'.", - portIter->first, - host.c_str())); - return portIter->first; - } - } - return 0; // no portNumber could be claimed + if (itsNrFreePorts == itsNrPorts) { // ready when nothing was claimed. + return; + } + + uint16 portNr = findService(aServiceName); + if (!portNr) { // unknown service? + return; + } + + int32 idx = portNr - itsLowerLimit; // convert portnr to array index + + LOG_INFO(formatString("Service %s(%d) unregistered", aServiceName.c_str(), portNr)); + + itsServiceList[idx].portNumber = 0; + itsServiceList[idx].serviceName = ""; + itsServiceList[idx].ownerPort = 0; + itsNrFreePorts++; + + LOG_INFO_STR ("Still managing " << itsNrPorts - itsNrFreePorts << " ports"); } -GSBController::TServiceInfo* GSBController::findService(const string& servicename) +// +// releasePort(port) +// +void GSBController::releasePort(GCFPortInterface* aPort) { - TServices::iterator iter = _services.find(servicename); - return (iter != _services.end() ? &iter->second : 0); + if (!aPort) { // check args + return; + } + + int32 idx = 0; + int32 nrElems2Check = itsNrPorts - itsNrFreePorts;// prevent checking whole array + + while (idx < itsNrPorts && nrElems2Check > 0) { + if (itsServiceList[idx].portNumber) { // used entry? + nrElems2Check--; + if (itsServiceList[idx].ownerPort == aPort) { + LOG_INFO(formatString("Service %s (%d) unregistered", + itsServiceList[idx].serviceName.c_str(), + itsServiceList[idx].portNumber)); + itsServiceList[idx].portNumber = 0; + itsServiceList[idx].serviceName = ""; + itsServiceList[idx].ownerPort = 0; + itsNrFreePorts++; + } + } + idx++; + } + LOG_INFO_STR ("Still managing " << itsNrPorts - itsNrFreePorts << " ports"); } -GSBController::TPortStates* GSBController::findHost(const string& host) +// +// findService(serviceName) +// +uint16 GSBController::findService(const string& aServiceName) { - // 1: find the host - TPortHosts::iterator iter = _availableHosts.find(host); - return (iter != _availableHosts.end() ? &iter->second : 0); + int32 idx = 0; + int32 nrElems2Check = itsNrPorts - itsNrFreePorts;// prevent checking whole array + + while (idx < itsNrPorts && nrElems2Check > 0) { + if (itsServiceList[idx].portNumber) { + nrElems2Check--; + if (itsServiceList[idx].serviceName == aServiceName) { + return (itsServiceList[idx].portNumber); + } + } + idx++; + } + + return (0); } + } // namespace SB } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.h b/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.h index a420cd1de67e6ee0ae98734a824d1282d490903e..dbfaaf72ae5438502bbdc59f9ba731c31af5d21c 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.h +++ b/MAC/GCF/TM/src/ServiceBroker/GSB_Controller.h @@ -26,17 +26,13 @@ #include <GCF/TM/GCF_Task.h> #include <GTM_SBTCPPort.h> -namespace LOFAR -{ - namespace GCF - { - namespace TM - { -class GCFEvent; -class GCFPortInterface; - } - namespace SB - { +namespace LOFAR { + namespace GCF { + namespace TM { + class GCFEvent; + class GCFPortInterface; + } + namespace SB { /** This is the main class of the Property Agent. It uses a number of helper @@ -47,49 +43,39 @@ class GCFPortInterface; class GSBController : public TM::GCFTask { - public: - GSBController(); - virtual ~GSBController(); +public: + GSBController(); + virtual ~GSBController(); - private: // state methods - TM::GCFEvent::TResult initial(TM::GCFEvent& e, TM::GCFPortInterface& p); - TM::GCFEvent::TResult operational(TM::GCFEvent& e, TM::GCFPortInterface& p); +private: + // state methods + TM::GCFEvent::TResult initial (TM::GCFEvent& e, TM::GCFPortInterface& p); + TM::GCFEvent::TResult operational(TM::GCFEvent& e, TM::GCFPortInterface& p); - private: // helper methods - typedef struct - { - string host; - unsigned int portNumber; - TM::GCFPortInterface* pPortToOwner; + typedef struct { + uint16 portNumber; + string serviceName; + TM::GCFPortInterface* ownerPort; } TServiceInfo; - void acceptConnectRequest(); - void clientGone(TM::GCFPortInterface& p); - void readRanges(); - unsigned int claimPortNumber(const string& host); - void cleanupGarbage(); - void freePort(const string& servicename, TServiceInfo* pServiceInfo); - - private: // data members - typedef map<string /*service(task:portname)*/, TServiceInfo> TServices; - TServices _services; + void acceptConnectRequest(); + void readRanges (); + uint16 claimPortNumber (const string& aServiceName, TM::GCFPortInterface* aPort); + void releaseService (const string& aServiceName); + void releasePort (TM::GCFPortInterface* aPort); + uint16 findService (const string& aServiceName); - typedef map<unsigned int /*portnumber*/, bool /*in use or not*/> TPortStates; - typedef map<string /*hostname*/, TPortStates> TPortHosts; - TPortHosts _availableHosts; + //# --- data members --- + vector<TServiceInfo> itsServiceList; // the administration + GTMSBTCPPort itsListener; // for all SB protocol messages - list<TM::GCFPortInterface*> _brokerClients; - list<TM::GCFPortInterface*> _brokerClientsGarbage; - GTMSBTCPPort _brokerProvider; + uint16 itsLowerLimit; // lowest portnr to assign + uint16 itsUpperLimit; // assign till this number + uint16 itsNrPorts; // number of ports to manage + uint16 itsNrFreePorts; // nr of not-assigned ports - TServiceInfo* findService(const string& servicename); - TPortStates* findHost(const string& host); - - private: // admin. data members - bool _isBusy; - bool _isRegistered; - unsigned int _counter; }; + } // namespace SB } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/TM/src/ServiceBroker/GSB_Defines.h b/MAC/GCF/TM/src/ServiceBroker/GSB_Defines.h index 71b15cb1bb3b59568fb325cedc9e9e05327b0ba1..b6dcde1e2fdc7464b09c8c31393d3b1ae2fe7048 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GSB_Defines.h +++ b/MAC/GCF/TM/src/ServiceBroker/GSB_Defines.h @@ -27,26 +27,23 @@ #include <GCF/GCF_Defines.h> -namespace LOFAR -{ - namespace GCF - { - namespace SB - { +namespace LOFAR { + namespace GCF { + namespace SB { class GCFPValue; -enum TSBResult -{ - SB_NO_ERROR, - SB_UNKNOWN_ERROR, - SB_SERVICE_ALREADY_EXIST, - SB_NO_FREE_PORTNR, - SB_UNKNOWN_SERVICE +enum TSBResult { + SB_NO_ERROR, + SB_UNKNOWN_ERROR, + SB_SERVICE_ALREADY_EXIST, + SB_NO_FREE_PORTNR, + SB_UNKNOWN_SERVICE }; -#define PARAM_SB_SERVER_PORT "mac.gcf.sb.port" -#define PARAM_SB_SERVER_HOST "mac.gcf.sb.host" +//#define PARAM_SB_SERVER_PORT "mac.gcf.sb.port" +//#define PARAM_SB_SERVER_HOST "mac.gcf.sb.host" + } // namespace SB } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/TM/src/ServiceBroker/GSB_Main.cc b/MAC/GCF/TM/src/ServiceBroker/GSB_Main.cc index 3c639b9db09ff269f1a5208a0b7d717d0b8eaa6a..9a19e86f95834d786260cc1249a36e045da3eb15 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GSB_Main.cc +++ b/MAC/GCF/TM/src/ServiceBroker/GSB_Main.cc @@ -25,9 +25,9 @@ #include <GSB_Controller.h> #include <GCF/TM/GCF_Control.h> -int main(int argC, char *argV[]) +int main(int argc, char *argv[]) { - GCFTask::init(argC, argV); + GCFTask::init(argc, argv); LOG_INFO("MACProcessScope: GCF.SB"); diff --git a/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc b/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc index 207cc0983e5bd722019644eb3e2bb4255f2d93b2..3012cefc7b6c75ac542a1da39680a7168f66adf7 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc +++ b/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc @@ -25,120 +25,106 @@ #include "GTM_SBTCPPort.h" #include <GTM_Defines.h> #include "GSB_Defines.h" +#include <GCF/GCF_ServiceInfo.h> #include <PortImpl/GTM_TCPServerSocket.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> -namespace LOFAR -{ - namespace GCF - { +namespace LOFAR { + namespace GCF { using namespace TM; - namespace SB - { + namespace SB { -GTMSBTCPPort::GTMSBTCPPort(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData) +// +// GTMSBTCPPort(task, name, type, protocol, raw) +// +GTMSBTCPPort::GTMSBTCPPort(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) : GCFTCPPort(task, name, type, protocol, transportRawData) { } +// +// GTMSBTCPPort() +// GTMSBTCPPort::GTMSBTCPPort() : GCFTCPPort() { } +// +// ~GTMSBTCPPort() +// GTMSBTCPPort::~GTMSBTCPPort() { - if (_pSocket) - { - delete _pSocket; - _pSocket = 0; - } + if (_pSocket) { + delete _pSocket; + _pSocket = 0; + } } +// +// open() +// bool GTMSBTCPPort::open() { - if (isConnected()) - { - LOG_ERROR(formatString ( - "Port %s already open.", - _name.c_str())); - return false; - } - else if (!_pSocket) - { - if (isSlave()) - { - LOG_ERROR(formatString ( - "Port %s not initialised.", - _name.c_str())); - return false; - } - else - { - if (SPP == getType() || MSPP == getType()) - { - _pSocket = new GTMTCPServerSocket(*this, (MSPP == getType())); - } - else if (SAP == getType()) - { - _pSocket = new GTMTCPSocket(*this); - } - } - } - - unsigned int sbPortNumber(0); - string sbHost; - try - { - sbPortNumber = ParameterSet::instance()->getInt(PARAM_SB_SERVER_PORT); - sbHost = ParameterSet::instance()->getString(PARAM_SB_SERVER_HOST); - } - catch (...) - { - LOG_FATAL("Could not get special portnumber param or host param for the Service Broker"); - GCFTask::stop(); - return false; - } - - if (_pSocket->open(sbPortNumber)) - { - if (SAP == getType()) - { - if (_pSocket->connect(sbPortNumber, sbHost)) - { - setState(S_CONNECTING); - schedule_connected(); - } - else - { - setState(S_DISCONNECTING); - schedule_disconnected(); - } - } - else if (MSPP == getType()) - { - setState(S_CONNECTING); - schedule_connected(); - } - } - else - { - setState(S_DISCONNECTING); - if (SAP == getType()) - { - schedule_disconnected(); - } - else - { - return false; - } - } - return true; + if (isConnected()) { + LOG_ERROR(formatString ("Port %s already open.", + makeServiceName().c_str())); + return false; + } + + if (!_pSocket) { + if (isSlave()) { + LOG_ERROR(formatString ("Port %s not initialised.", + makeServiceName().c_str())); + return false; + } + + if (SPP == getType() || MSPP == getType()) { + _pSocket = new GTMTCPServerSocket(*this, (MSPP == getType())); + } + else if (SAP == getType()) { + _pSocket = new GTMTCPSocket(*this); + } + } + + uint32 sbPortNumber(MAC_SERVICEBROKER_PORT); + string sbHost ("localhost"); + char hostname[256]; + if (gethostname(hostname, 256) == 0) { + sbHost = hostname; + } + + if (_pSocket->open(sbPortNumber)) { + if (SAP == getType()) { + if (_pSocket->connect(sbPortNumber, sbHost)) { + setState(S_CONNECTING); + schedule_connected(); + } + else { + setState(S_DISCONNECTING); + schedule_disconnected(); + } + } + else if (MSPP == getType()) { + setState(S_CONNECTING); + schedule_connected(); + } + } + else { + setState(S_DISCONNECTING); + if (SAP == getType()) { + schedule_disconnected(); + } + else { + return false; + } + } + return true; } } // namespace SB } // namespace GCF diff --git a/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.h b/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.h index 3002c490b71e0e6cbb830419999f8f23ffca2fd6..4b10b4dba64e6ffdb891585204291f1cb8421c29 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.h +++ b/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.h @@ -45,11 +45,11 @@ class GTMSBTCPPort : public TM::GCFTCPPort /// Construction methods /** @param protocol NOT USED */ - explicit GTMSBTCPPort (TM::GCFTask& task, - string name, - TM::GCFPortInterface::TPortType type, - int protocol, - bool transportRawData = false); + explicit GTMSBTCPPort (TM::GCFTask& task, + const string& name, + TM::GCFPortInterface::TPortType type, + int protocol, + bool transportRawData = false); explicit GTMSBTCPPort (); virtual ~GTMSBTCPPort (); diff --git a/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.cc b/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.cc index 1704383f2edec08ba78d5069c3cda5ede19552e2..67f13f6a8bb7e6ecc58c67dc5b57450fda010bec 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.cc +++ b/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.cc @@ -21,312 +21,320 @@ //# $Id$ #include <lofar_config.h> +#include <Common/LofarLocators.h> #include "GTM_ServiceBroker.h" #include <SB_Protocol.ph> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> #include <GTM_Defines.h> #include "GSB_Defines.h" #include <unistd.h> -namespace LOFAR -{ - namespace GCF - { +namespace LOFAR { + namespace GCF { using namespace TM; - namespace SB - { + namespace SB { +// +// Initialize static elements static string sSBTaskName("GCF-SB"); GTMSBHandler* GTMSBHandler::_pInstance = 0; -extern void logResult(TSBResult result, const string& servicename); +// +// logResult +// +void logResult(TSBResult result, const string& servicename) +{ + switch (result) { + case SB_NO_ERROR: + break; + case SB_UNKNOWN_ERROR: + LOG_FATAL("Unknown error"); + break; + case SB_SERVICE_ALREADY_EXIST: + LOG_ERROR(formatString ( "Service %s already exist", servicename.c_str())); + break; + case SB_NO_FREE_PORTNR: + LOG_ERROR(formatString ( "No free portnumber for this service: %s", servicename.c_str())); + break; + case SB_UNKNOWN_SERVICE: + LOG_FATAL(formatString ( "Unknown remote service: %s", servicename.c_str())); + break; + default: + break; + } +} +// +// GTMSBHandler() +// GTMSBHandler::GTMSBHandler() { } +// +// GTMServiceBroker() +// GTMServiceBroker::GTMServiceBroker() : - GCFTask((State)>MServiceBroker::initial, sSBTaskName) + GCFTask((State)>MServiceBroker::initial, sSBTaskName) { - // register the protocol for debugging purposes - registerProtocol(SB_PROTOCOL, SB_PROTOCOL_signalnames); + // register the protocol for debugging purposes + registerProtocol(SB_PROTOCOL, SB_PROTOCOL_signalnames); - // initialize the port - _serviceBroker.init(*this, "client", GCFPortInterface::SAP, SB_PROTOCOL); - ParameterSet::instance()->adoptFile("ServiceBroker.conf"); + // initialize the port + _serviceBroker.init(*this, "client", GCFPortInterface::SAP, SB_PROTOCOL); } +// +// ~GTMServiceBroker() +// GTMServiceBroker::~GTMServiceBroker() { } +// +// instance(temp) +// GTMServiceBroker* GTMServiceBroker::instance(bool temporary) { - if (0 == GTMSBHandler::_pInstance) - { - GTMSBHandler::_pInstance = new GTMSBHandler(); - ASSERT(!GTMSBHandler::_pInstance->mayDeleted()); - GTMSBHandler::_pInstance->_controller.start(); - } - if (!temporary) GTMSBHandler::_pInstance->use(); - return >MSBHandler::_pInstance->_controller; + if (!GTMSBHandler::_pInstance) { + GTMSBHandler::_pInstance = new GTMSBHandler(); + ASSERT(!GTMSBHandler::_pInstance->mayDeleted()); + GTMSBHandler::_pInstance->_controller.start(); + } + + if (!temporary) { + GTMSBHandler::_pInstance->use(); + } + + return >MSBHandler::_pInstance->_controller; } +// +// release() +// void GTMServiceBroker::release() { - ASSERT(GTMSBHandler::_pInstance); - ASSERT(!GTMSBHandler::_pInstance->mayDeleted()); - GTMSBHandler::_pInstance->leave(); - if (GTMSBHandler::_pInstance->mayDeleted()) - { - delete GTMSBHandler::_pInstance; - ASSERT(!GTMSBHandler::_pInstance); - } + ASSERT(GTMSBHandler::_pInstance); + ASSERT(!GTMSBHandler::_pInstance->mayDeleted()); + GTMSBHandler::_pInstance->leave(); + if (GTMSBHandler::_pInstance->mayDeleted()) { + delete GTMSBHandler::_pInstance; + ASSERT(!GTMSBHandler::_pInstance); + } } +// +// registerService(servicePort) +// void GTMServiceBroker::registerService(GCFTCPPort& servicePort) { - string servicename = formatString("%s:%s", - servicePort.getTask()->getName().c_str(), - servicePort.getRealName().c_str()); - char hostName[200]; - gethostname(hostName, 200); - - SBRegisterServiceEvent request; - - TAction action; - action.action = request.signal; - action.pPort = &servicePort; - action.servicename = servicename; - - request.seqnr = registerAction(action); - request.host = hostName; - request.servicename = servicename; - - if (_serviceBroker.isConnected()) - { - _serviceBroker.send(request); - } + string servicename = servicePort.makeServiceName(); + + SBRegisterServiceEvent request; + + TAction action; + action.action = request.signal; + action.pPort = &servicePort; + action.servicename = servicename; + + request.seqnr = registerAction(action); + request.servicename = servicename; + + if (_serviceBroker.isConnected()) { + _serviceBroker.send(request); + } } +// +// unregisterService(servicePort) +// void GTMServiceBroker::unregisterService(GCFTCPPort& servicePort) { - string servicename = formatString("%s:%s", - servicePort.getTask()->getName().c_str(), - servicePort.getRealName().c_str()); + SBUnregisterServiceEvent request; - SBUnregisterServiceEvent request; + request.servicename = servicePort.makeServiceName(); - request.servicename = servicename; - - if (_serviceBroker.isConnected()) - { - _serviceBroker.send(request); - } + if (_serviceBroker.isConnected()) { + _serviceBroker.send(request); + } } -void GTMServiceBroker::getServiceinfo(GCFTCPPort& clientPort, const string& remoteServiceName) +// +// getServiceinfo(clientPort, remoteServiceName); +// +void GTMServiceBroker::getServiceinfo(GCFTCPPort& clientPort, + const string& remoteServiceName, + const string& hostname) { - SBGetServiceinfoEvent request; - TAction action; - action.action = request.signal; - action.pPort = &clientPort; - action.servicename = remoteServiceName; - request.seqnr = registerAction(action); - request.servicename = remoteServiceName; - - if (_serviceBroker.isConnected()) - { - _serviceBroker.send(request); - } + SBGetServiceinfoEvent request; + + TAction action; + action.action = request.signal; + action.pPort = &clientPort; + action.servicename = remoteServiceName; + + request.seqnr = registerAction(action); + request.servicename = remoteServiceName; + request.hostname = hostname; + + if (_serviceBroker.isConnected()) { + _serviceBroker.send(request); + } } +// +// deletePort(port) +// void GTMServiceBroker::deletePort(GCFTCPPort& port) { - TAction* pAction; - unregisterService(port); - for (TActionSeqList::iterator iter = _actionSeqList.begin(); - iter != _actionSeqList.end(); ++iter) - { - pAction = &iter->second; - if (pAction->pPort == &port) - { - _actionSeqList.erase(iter); - break; - } - } - for (TServiceClients::iterator iter = _serviceClients.begin(); - iter != _serviceClients.end(); ++iter) - { - list<GCFTCPPort*>* pClientPorts = &iter->second; - pClientPorts->remove(&port); - } + TAction* pAction; + for (TActionSeqList::iterator iter = _actionSeqList.begin(); + iter != _actionSeqList.end(); ++iter) { + pAction = &iter->second; + if (pAction->pPort == &port) { + _actionSeqList.erase(iter); + break; + } + } + + for (TServiceClients::iterator iter = _serviceClients.begin(); + iter != _serviceClients.end(); ++iter) { + list<GCFTCPPort*>* pClientPorts = &iter->second; + pClientPorts->remove(&port); + } } +// +// registerAction(action) +// unsigned short GTMServiceBroker::registerAction(TAction action) { - unsigned short seqnr(1); // 0 is reserved for internal msg. in SB - TActionSeqList::const_iterator iter; - do - { - seqnr++; - iter = _actionSeqList.find(seqnr); - } while (iter != _actionSeqList.end()); + unsigned short seqnr(1); // 0 is reserved for internal msg. in SB + TActionSeqList::const_iterator iter; + do { + seqnr++; + iter = _actionSeqList.find(seqnr); + } while (iter != _actionSeqList.end()); - _actionSeqList[seqnr] = action; + _actionSeqList[seqnr] = action; - return seqnr; + return seqnr; } +// +// initial(event, port) +// GCFEvent::TResult GTMServiceBroker::initial(GCFEvent& e, GCFPortInterface& /*p*/) { - GCFEvent::TResult status = GCFEvent::HANDLED; - switch (e.signal) - { - case F_INIT: - break; - - case F_ENTRY: - case F_TIMER: - _serviceBroker.open(); - break; - - case F_CONNECTED: - TRAN(GTMServiceBroker::operational); - break; - - case F_DISCONNECTED: - _serviceBroker.setTimer(1.0); // try again after 1 second - break; - - default: - status = GCFEvent::NOT_HANDLED; - break; - } - - return status; + GCFEvent::TResult status = GCFEvent::HANDLED; + switch (e.signal) { + case F_INIT: + break; + + case F_ENTRY: + case F_TIMER: + _serviceBroker.open(); + break; + + case F_CONNECTED: + TRAN(GTMServiceBroker::operational); + break; + + case F_DISCONNECTED: + _serviceBroker.setTimer(1.0); // try again after 1 second + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; } +// +// operational(event, port) +// GCFEvent::TResult GTMServiceBroker::operational(GCFEvent& e, GCFPortInterface& p) { - GCFEvent::TResult status = GCFEvent::HANDLED; - - switch (e.signal) - { - case F_DISCONNECTED: - LOG_FATAL("Connection lost to Service Broker deamon"); - p.close(); - break; - case F_CLOSED: - TRAN(GTMServiceBroker::initial); - break; - case F_ENTRY: - { - TAction* pAction(0); - TActionSeqList tmpSeqList(_actionSeqList); - _actionSeqList.clear(); - for (TActionSeqList::iterator iter = tmpSeqList.begin(); - iter != tmpSeqList.end(); ++iter) - { - pAction = &iter->second; - switch (pAction->action) - { - case SB_REGISTER_SERVICE: registerService(*pAction->pPort); break; - case SB_UNREGISTER_SERVICE: unregisterService(*pAction->pPort); break; - case SB_GET_SERVICEINFO: getServiceinfo(*pAction->pPort, pAction->servicename); break; - default: ASSERT(0); - } - } - - break; - } - case SB_SERVICE_REGISTERED: - { - SBServiceRegisteredEvent response(e); - TAction* pAction = &_actionSeqList[response.seqnr]; - if (pAction) - { - logResult(response.result, pAction->servicename); - _actionSeqList.erase(response.seqnr); - pAction->pPort->serviceRegistered(response.result, response.portnumber); - } - break; - } - - case SB_SERVICE_INFO: - { - SBServiceInfoEvent response(e); - TAction* pAction = &_actionSeqList[response.seqnr]; - if (pAction) - { - logResult(response.result, pAction->servicename); - if (response.result == SB_NO_ERROR) - { - _serviceClients[pAction->servicename].push_back(pAction->pPort); - } - _actionSeqList.erase(response.seqnr); - pAction->pPort->serviceInfo(response.result, response.portnumber, response.host); - } - break; - } - - case SB_SERVICE_GONE: - { - SBServiceGoneEvent indication(e); - TServiceClients::iterator iter = _serviceClients.find(indication.servicename); - if (iter != _serviceClients.end()) - { - list<GCFTCPPort*>* pClientPorts = &iter->second; - GCFTCPPort* pClientPort; - for (list<GCFTCPPort*>::iterator cIter = pClientPorts->begin(); - cIter != pClientPorts->end(); ++cIter) - { - pClientPort = *cIter; - pClientPort->serviceGone(); - } - } - _serviceClients.erase(indication.servicename); - - break; - } - default: - status = GCFEvent::NOT_HANDLED; - break; - } - - return status; + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (e.signal) { + case F_DISCONNECTED: + LOG_FATAL("Connection lost to Service Broker deamon"); + p.close(); + break; + + case F_CLOSED: + TRAN(GTMServiceBroker::initial); + break; + + case F_ENTRY: { + TAction* pAction(0); + TActionSeqList tmpSeqList(_actionSeqList); + _actionSeqList.clear(); + for (TActionSeqList::iterator iter = tmpSeqList.begin(); + iter != tmpSeqList.end(); ++iter) { + pAction = &iter->second; + switch (pAction->action) { + case SB_REGISTER_SERVICE: + registerService(*pAction->pPort); + break; + case SB_UNREGISTER_SERVICE: + unregisterService(*pAction->pPort); + break; + case SB_GET_SERVICEINFO: + getServiceinfo(*pAction->pPort, pAction->servicename, pAction->hostname); + break; + default: + ASSERT(0); + } + } + break; + } + + case SB_SERVICE_REGISTERED: { + SBServiceRegisteredEvent response(e); + TAction* pAction = &_actionSeqList[response.seqnr]; + if (pAction) { + logResult(response.result, pAction->servicename); + _actionSeqList.erase(response.seqnr); + pAction->pPort->serviceRegistered(response.result, response.portnumber); + } + break; + } + + case SB_SERVICE_INFO: { + SBServiceInfoEvent response(e); + TAction* pAction = &_actionSeqList[response.seqnr]; + if (pAction) { + logResult(response.result, pAction->servicename); + if (response.result == SB_NO_ERROR) { + _serviceClients[pAction->servicename].push_back(pAction->pPort); + } + _actionSeqList.erase(response.seqnr); + pAction->pPort->serviceInfo(response.result, response.portnumber, response.hostname); + } + break; + } + + case SB_SERVICE_GONE: { + SBServiceGoneEvent indication(e); + _serviceClients.erase(indication.servicename); + break; + } + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; } -void logResult(TSBResult result, const string& servicename) -{ - switch (result) - { - case SB_NO_ERROR: - break; - case SB_UNKNOWN_ERROR: - LOG_FATAL("Unknown error"); - break; - case SB_SERVICE_ALREADY_EXIST: - LOG_ERROR(formatString ( - "Service %s already exist", - servicename.c_str())); - break; - case SB_NO_FREE_PORTNR: - LOG_ERROR(formatString ( - "No free portnumber for this service: %s", - servicename.c_str())); - break; - case SB_UNKNOWN_SERVICE: - LOG_FATAL(formatString ( - "Unkown remote service: %s", - servicename.c_str())); - break; - default: - break; - } -} + } // namespace SB } // namespace GCF } // namespace LOFAR diff --git a/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.h b/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.h index fec79e9e807a9be437370a8535c566b2699bc9b3..49a77bc223b413c40c95f667be19ac1047656558 100644 --- a/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.h +++ b/MAC/GCF/TM/src/ServiceBroker/GTM_ServiceBroker.h @@ -48,10 +48,12 @@ class GTMServiceBroker : public TM::GCFTask static void release(); public: // member functions - void registerService(TM::GCFTCPPort& servicePort); - void unregisterService(TM::GCFTCPPort& servicePort); - void getServiceinfo (TM::GCFTCPPort& clientPort, const string& remoteServiceName); - void deletePort(TM::GCFTCPPort& port); + void registerService (TM::GCFTCPPort& servicePort); + void unregisterService(TM::GCFTCPPort& servicePort); + void getServiceinfo (TM::GCFTCPPort& clientPort, + const string& remoteServiceName, + const string& hostname = "localhost"); + void deletePort (TM::GCFTCPPort& port); private: friend class GTMSBHandler; @@ -64,16 +66,18 @@ class GTMServiceBroker : public TM::GCFTask private: // helper methods typedef struct Action { - unsigned short action; - TM::GCFTCPPort* pPort; - string servicename; + unsigned short action; + TM::GCFTCPPort* pPort; + string servicename; + string hostname; Action& operator= (const Action& other) { if (this != &other) { - action = other.action; - pPort = other.pPort; - servicename.replace(0, string::npos, other.servicename); + action = other.action; + pPort = other.pPort; + servicename = other.servicename; + hostname = other.hostname; } return *this; } diff --git a/MAC/GCF/TM/src/ServiceBroker/Makefile.am b/MAC/GCF/TM/src/ServiceBroker/Makefile.am index 1776af51becc8de12adc37db6a063b7ea6d880be..97b6a2bf89213e6fbc31edf4d61b85c7773caec0 100644 --- a/MAC/GCF/TM/src/ServiceBroker/Makefile.am +++ b/MAC/GCF/TM/src/ServiceBroker/Makefile.am @@ -1,40 +1,21 @@ -DOCHDRS = \ - GSB_Controller.h \ - GSB_Defines.h +DOCHDRS = GSB_Controller.h \ + GSB_Defines.h -noinst_LTLIBRARIES = libsb.la - -libsb_la_SOURCES= $(DOCHDRS) \ - GSB_Controller.cc - -libsb_la_CXXFLAGS=-fmessage-length=0 - -bin_PROGRAMS = ServiceBroker +bin_PROGRAMS = ServiceBroker -ServiceBroker_SOURCES = GSB_Main.cc -ServiceBroker_LDADD = libsb.la $(LOFAR_DEPEND) \ - $(top_builddir)/src/libgcftm.la +ServiceBroker_SOURCES = GSB_Controller.cc GSB_Main.cc +ServiceBroker_LDADD = $(top_builddir)/src/libgcftm.la $(LOFAR_DEPEND) +ServiceBroker_DEPENDENCIES = $(top_builddir)/src/libgcftm.la $(LOFAR_DEPEND) -ServiceBroker_DEPENDENCIES = libsb.la $(LOFAR_DEPEND) \ - $(top_builddir)/src/libgcftm.la - -ServiceBroker_CXXFLAGS=-fmessage-length=0 +ServiceBroker_CXXFLAGS = -fmessage-length=0 -BUILT_SOURCES = +BUILT_SOURCES = -EXTRA_DIST = $(sysconf_DATA) +EXTRA_DIST = $(sysconf_DATA) -sysconf_DATA= \ - ServiceBroker.conf +sysconf_DATA = ServiceBroker.conf -install-data-local: - f=$(DESTDIR)$(sysconfdir)/ServiceBroker.conf; \ - hs=`hostname -s`; \ - h=`hostname`; \ - n=`sed -e "/mac.gcf.sb.host=/ s/\(.*\)=\(.*\)/\1=$$hs/" -e "/mac.gcf.sb.range1.host=/ s/\(.*\)=\(.*\)/\1=$$h/" $$f`; \ - echo "$$n" > $$f; - -%.conf: gcf-sb.conf.in +%.conf: ServiceBroker.conf.in cp $< $@ include $(top_srcdir)/Makefile.common diff --git a/MAC/GCF/TM/src/ServiceBroker/SB_Protocol.prot b/MAC/GCF/TM/src/ServiceBroker/SB_Protocol.prot index da357660259335cdfe4034e763c6aee1363bac16..cf7b5ef319c843af4677034415d47095fc16714d 100644 --- a/MAC/GCF/TM/src/ServiceBroker/SB_Protocol.prot +++ b/MAC/GCF/TM/src/ServiceBroker/SB_Protocol.prot @@ -27,10 +27,6 @@ event = { name = "servicename"; type = "string"; }; - param = { - name = "host"; - type = "string"; - }; }; event = { @@ -53,6 +49,10 @@ event = { name = "servicename"; type = "string"; }; + param = { + name = "hostname"; + type = "string"; + }; }; event = { @@ -84,7 +84,7 @@ event = { type = "unsigned int"; }; param = { - name = "host"; + name = "hostname"; type = "string"; }; param = { @@ -100,4 +100,4 @@ event = { name = "servicename"; type = "string"; }; -}; \ No newline at end of file +}; diff --git a/MAC/GCF/TM/src/ServiceBroker/ServiceBroker.conf.in b/MAC/GCF/TM/src/ServiceBroker/ServiceBroker.conf.in new file mode 100644 index 0000000000000000000000000000000000000000..c59a829c2cccf0e3a437da557333ba39f52df48b --- /dev/null +++ b/MAC/GCF/TM/src/ServiceBroker/ServiceBroker.conf.in @@ -0,0 +1,6 @@ +# ParameterSet for ServiceBroker +# +#mac.gcf.sb.port=24000 +firstPortNumber = 24001 +lastPortNumber = 25000 + diff --git a/MAC/GCF/TM/src/ServiceBroker/gcf-sb.conf.in b/MAC/GCF/TM/src/ServiceBroker/gcf-sb.conf.in deleted file mode 100644 index 0231ac6dc6467c9544205940beeca82020ba7f0c..0000000000000000000000000000000000000000 --- a/MAC/GCF/TM/src/ServiceBroker/gcf-sb.conf.in +++ /dev/null @@ -1,5 +0,0 @@ -mac.gcf.sb.port=24000 -mac.gcf.sb.range1.firstPortNumber=24001 -mac.gcf.sb.range1.lastPortNumber=25000 -mac.gcf.sb.host= -mac.gcf.sb.range1.host= diff --git a/MAC/GCF/TM/test/Makefile.am b/MAC/GCF/TM/test/Makefile.am index 99d599d4e16d15b745ee9a74e4f8b7cc691afe48..d76283394c5262152b65074de12d617b9f75942b 100644 --- a/MAC/GCF/TM/test/Makefile.am +++ b/MAC/GCF/TM/test/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = tmEcho tmPing +bin_PROGRAMS = tmEcho tmPing tGCFPort tmEcho_SOURCES = $(BUILT_SOURCES) Echo_Protocol.cc Echo.cc Echo.h tmEcho_LDADD = ../src/libgcftm.la @@ -8,6 +8,11 @@ tmPing_SOURCES = $(BUILT_SOURCES) Echo_Protocol.cc Ping.cc Ping.h tmPing_LDADD = ../src/libgcftm.la tmPing_DEPENDENCIES = ../src/libgcftm.la $(LOFAR_DEPEND) +tGCFPort_SOURCES = $(BUILT_SOURCES) Echo_Protocol.cc \ + tGCFPort.cc tGCFPort.h +tGCFPort_LDADD = ../src/libgcftm.la +tGCFPort_DEPENDENCIES = ../src/libgcftm.la $(LOFAR_DEPEND) + AUTOGEN = autogen SUFFIXES = .ph %.ph: %.prot @@ -19,7 +24,8 @@ EXTRA_DIST = $(sysconf_DATA) sysconf_DATA=\ tmEcho.conf \ - tmPing.conf + tmPing.conf \ + tGCFPort.conf %.conf: tm-test.conf.in ln -sf $< $@ diff --git a/MAC/GCF/TM/test/tGCFPort.cc b/MAC/GCF/TM/test/tGCFPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..74f940af35a26b9a84f21b77dd5fe2fb2d34ab4b --- /dev/null +++ b/MAC/GCF/TM/test/tGCFPort.cc @@ -0,0 +1,943 @@ +// +// tGCFPort.cc: Test program to test all kind of usage of the GCF ports. +// +// 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 "tGCFPort.h" +#include "Echo_Protocol.ph" + +namespace LOFAR { + namespace GCF { + namespace TM { + + +// Constructors of both classes +tServer::tServer(string name) : + GCFTask ((State)&tServer::test1, name), + itsServerPort (0), + itsTimeoutTimer (0), + itsFinished (false) +{ + registerProtocol(ECHO_PROTOCOL, ECHO_PROTOCOL_signalnames); +} + +tClient::tClient(string name) : + GCFTask ((State)&tClient::test1, name), + itsClientPort (0), + itsTimeoutTimer (0), + itsFinishedTimer(0) +{ + registerProtocol(ECHO_PROTOCOL, ECHO_PROTOCOL_signalnames); +} + +void tServer::finishTest(uint32 testnr) +{ + LOG_INFO_STR ("Server:Ending test" << testnr); + itsServerPort->cancelAllTimers(); + delete itsServerPort; + itsServerPort = 0; + itsTimeoutTimer = 0; + itsFinished = false; +} + +void tClient::finishTest(uint32 testnr) +{ + LOG_INFO_STR ("Client:Ending test" << testnr); + itsClientPort->cancelAllTimers(); + delete itsClientPort; + itsClientPort = 0; + itsTimeoutTimer = 0; + itsFinishedTimer = 0; +} + +// +// TEST 1 +// +// The server opens a TCP port with name SERVER:test1 using the settings in +// the configuration file. +// The client tries to resolve the label CLIENT:1stTest into the right +// service name of the server using the config files and serviceBroker. +// +GCFEvent::TResult tServer::test1(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Server@test1: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsServerPort = new GCFPort(*this, "test1", GCFPortInterface::SPP, + ECHO_PROTOCOL); + ASSERTSTR(itsServerPort, "Failed to open serverport in test1"); + LOG_INFO("Server:Starting test1"); + itsTimeoutTimer = itsServerPort->setTimer(30.0); // max duration of test + itsServerPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("SERVER: TEST 1 FAILED ON TIMEOUT"); + gError |= 0x01; + itsServerPort->close(); // results in disconnected event. + itsFinished = true; + break; + } + // 'open' timer expired, retry to open the server port. + if (!itsServerPort->isConnected()) { + itsServerPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsServerPort->isConnected()) { + // Alright, the server port is open wait for client or + // max testtime timer. + } + break; + + case F_CLOSED: + case F_DISCONNECTED: + if (itsFinished) { // timer exists when msg was received. + finishTest(1); + TRAN(tServer::test2); + } + else { + itsServerPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_PING: { + EchoPingEvent ping(event); + LOG_INFO_STR ("Server:PING received, seqnr=" << ping.seqnr); + + // Construct echo message and send it. + timeval echo_time; + gettimeofday(&echo_time, 0); + EchoEchoEvent echo; + echo.seqnr = ping.seqnr; + echo.ping_time = ping.ping_time; + echo.echo_time = echo_time; + + itsServerPort->send(echo); + itsFinished = true; + + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult tClient::test1(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Client@test1: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsClientPort = new GCFPort(*this, "1stTest", GCFPortInterface::SAP, + ECHO_PROTOCOL); + ASSERTSTR(itsClientPort, "Failed to create a clientport in test1"); + LOG_INFO("Client:Starting test1"); + itsTimeoutTimer = itsClientPort->setTimer(30.0); // max duration of test + itsClientPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); + if ((timerEvent.id == itsTimeoutTimer) || + (timerEvent.id == itsFinishedTimer)) { + + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("CLIENT: TEST 1 FAILED ON TIMEOUT"); + gError |= 0x01; + } + itsClientPort->close(); // results in disconnected event. + itsFinishedTimer = ~0; + break; + } + // 'open' timer expired, retry to open the client port. + if (!itsClientPort->isConnected()) { + itsClientPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsClientPort->isConnected()) { + // create PingEvent + timeval ping_time; + gettimeofday(&ping_time, 0); + + EchoPingEvent ping; + ping.seqnr = 1; + ping.ping_time = ping_time; + + // send the event + itsClientPort->send(ping); + LOG_INFO_STR("Client:PING sent (seqnr=" << ping.seqnr); + } + break; + + case F_DISCONNECTED: + port.close(); + case F_CLOSED: + if (itsFinishedTimer) { + LOG_INFO ("Client:Lost connection with server"); + finishTest(1); + TRAN(tClient::test2); + } + else { + itsClientPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_ECHO: { + EchoEchoEvent echo(event); + LOG_INFO_STR("client:ECHO received, seqnr=" << echo.seqnr); + itsFinishedTimer = itsClientPort->setTimer(0.5); + } + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +// +// TEST2 +// +// The server opens a TCP port with name SERVER:test2 using the settings in +// the configuration file. +// The client tries to open the port "SERVER:test2" without the configfiles. +// +GCFEvent::TResult tServer::test2(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Server@test2: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsServerPort = new GCFPort(*this, "test2", GCFPortInterface::SPP, + ECHO_PROTOCOL); + ASSERTSTR(itsServerPort, "Failed to open serverport in test2"); + LOG_INFO("Server:Starting test2"); + itsTimeoutTimer = itsServerPort->setTimer(30.0); // max duration of test + itsServerPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("SERVER: TEST 2 FAILED ON TIMEOUT"); + gError |= 0x02; + itsServerPort->close(); // results in disconnected event + itsFinished = true; + break; + } + // 'open' timer expired, retry to open the server port. + if (!itsServerPort->isConnected()) { + itsServerPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsServerPort->isConnected()) { + // Alright, the server port is open wait for client or + // max testtime timer. + } + break; + + case F_CLOSED: + case F_DISCONNECTED: + if (itsFinished) { // timer exists when msg was received. + finishTest(2); + TRAN(tServer::test3); + } + else { + itsServerPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_PING: { + EchoPingEvent ping(event); + LOG_INFO_STR ("Server:PING received, seqnr=" << ping.seqnr); + + // Construct echo message and send it. + timeval echo_time; + gettimeofday(&echo_time, 0); + EchoEchoEvent echo; + echo.seqnr = ping.seqnr; + echo.ping_time = ping.ping_time; + echo.echo_time = echo_time; + + itsServerPort->send(echo); + itsFinished = true; + + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult tClient::test2(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Client@test2: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsClientPort = new GCFPort(*this, "SERVER:test2", + GCFPortInterface::SAP, ECHO_PROTOCOL); + ASSERTSTR(itsClientPort, "Failed to create a clientport in test2"); + LOG_INFO("Client:Starting test2"); + itsTimeoutTimer = itsClientPort->setTimer(30.0); // max duration of test + itsClientPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); + if ((timerEvent.id == itsTimeoutTimer) || + (timerEvent.id == itsFinishedTimer)) { + + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("CLIENT: TEST 2 FAILED ON TIMEOUT"); + gError |= 0x02; + } + itsClientPort->close(); // results in disconected event + itsFinishedTimer = ~0; + break; + } + // 'open' timer expired, retry to open the client port. + if (!itsClientPort->isConnected()) { + itsClientPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsClientPort->isConnected()) { + // create PingEvent + timeval ping_time; + gettimeofday(&ping_time, 0); + + EchoPingEvent ping; + ping.seqnr = 2; + ping.ping_time = ping_time; + + // send the event + itsClientPort->send(ping); + LOG_INFO_STR("Client:PING sent (seqnr=" << ping.seqnr); + } + break; + + case F_DISCONNECTED: + port.close(); + case F_CLOSED: + if (itsFinishedTimer) { + LOG_INFO ("Client:Lost connection with server"); + finishTest(2); + TRAN(tClient::test3); + } + else { + itsClientPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_ECHO: { + EchoEchoEvent echo(event); + LOG_INFO_STR("client:ECHO received, seqnr=" << echo.seqnr); + itsFinishedTimer = itsClientPort->setTimer(0.5); + } + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + + +// +// TEST3 +// +// The server opens a TCP port with name "SERVER:test3" without using the +// configuration files. +// The client tries to resolve the label CLIENT:3rdTest into the right +// service name of the server using the config files and serviceBroker. +// +// +GCFEvent::TResult tServer::test3(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Server@test3: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsServerPort = new GCFPort(*this, "SERVER:test3", + GCFPortInterface::SPP, ECHO_PROTOCOL); + ASSERTSTR(itsServerPort, "Failed to open serverport in test3"); LOG_INFO("Server:Starting test3"); + itsTimeoutTimer = itsServerPort->setTimer(30.0); // max duration of test + itsServerPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("SERVER: TEST 3 FAILED ON TIMEOUT"); + gError |= 0x04; + itsServerPort->close(); // results in disconnected event + itsFinished = true; + break; + } + // 'open' timer expired, retry to open the server port. + if (!itsServerPort->isConnected()) { + itsServerPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsServerPort->isConnected()) { + // Alright, the server port is open wait for client or + // max testtime timer. + } + break; + + case F_CLOSED: + case F_DISCONNECTED: + if (itsFinished) { // timer exists when msg was received. + finishTest(3); + TRAN(tServer::test4); + } + else { + itsServerPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_PING: { + EchoPingEvent ping(event); + LOG_INFO_STR ("Server:PING received, seqnr=" << ping.seqnr); + + // Construct echo message and send it. + timeval echo_time; + gettimeofday(&echo_time, 0); + EchoEchoEvent echo; + echo.seqnr = ping.seqnr; + echo.ping_time = ping.ping_time; + echo.echo_time = echo_time; + + itsServerPort->send(echo); + itsFinished = true; + + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult tClient::test3(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Client@test3: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsClientPort = new GCFPort(*this, "3rdTest", + GCFPortInterface::SAP, ECHO_PROTOCOL); + ASSERTSTR(itsClientPort, "Failed to create a clientport in test3"); + LOG_INFO("Client:Starting test3"); + itsTimeoutTimer = itsClientPort->setTimer(30.0); // max duration of test + itsClientPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); + if ((timerEvent.id == itsTimeoutTimer) || + (timerEvent.id == itsFinishedTimer)) { + + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("CLIENT: TEST 3 FAILED ON TIMEOUT"); + gError |= 0x04; + } + itsClientPort->close(); // results in disconnected event + itsFinishedTimer = ~0; + break; + } + // 'open' timer expired, retry to open the client port. + if (!itsClientPort->isConnected()) { + itsClientPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsClientPort->isConnected()) { + // create PingEvent + timeval ping_time; + gettimeofday(&ping_time, 0); + + EchoPingEvent ping; + ping.seqnr = 3; + ping.ping_time = ping_time; + + // send the event + itsClientPort->send(ping); + LOG_INFO_STR("Client:PING sent (seqnr=" << ping.seqnr); + } + break; + + case F_DISCONNECTED: + port.close(); + case F_CLOSED: + if (itsFinishedTimer) { + LOG_INFO ("Client:Lost connection with server"); + finishTest(3); + TRAN(tClient::test4); + } + else { + itsClientPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_ECHO: { + EchoEchoEvent echo(event); + LOG_INFO_STR("client:ECHO received, seqnr=" << echo.seqnr); + itsFinishedTimer = itsClientPort->setTimer(0.5); + } + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +// +// TEST 4 +// +// The server opens a TCP port with name "SERVER:test4" without using the +// configuration files, the client also. +// +GCFEvent::TResult tServer::test4(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Server@test4: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsServerPort = new GCFPort(*this, "SERVER:test4", + GCFPortInterface::SPP, ECHO_PROTOCOL); + ASSERTSTR(itsServerPort, "Failed to open serverport in test4"); LOG_INFO("Server:Starting test4"); + itsTimeoutTimer = itsServerPort->setTimer(30.0); // max duration of test + itsServerPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("SERVER: TEST 4 FAILED ON TIMEOUT"); + gError |= 0x08; + itsServerPort->close(); // results in disconnected event + itsFinished = true; + break; + } + // 'open' timer expired, retry to open the server port. + if (!itsServerPort->isConnected()) { + itsServerPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsServerPort->isConnected()) { + // Alright, the server port is open wait for client or + // max testtime timer. + } + break; + + case F_CLOSED: + case F_DISCONNECTED: + if (itsFinished) { // timer exists when msg was received. + finishTest(4); + TRAN(tServer::test5); + } + else { + itsServerPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_PING: { + EchoPingEvent ping(event); + LOG_INFO_STR ("Server:PING received, seqnr=" << ping.seqnr); + + // Construct echo message and send it. + timeval echo_time; + gettimeofday(&echo_time, 0); + EchoEchoEvent echo; + echo.seqnr = ping.seqnr; + echo.ping_time = ping.ping_time; + echo.echo_time = echo_time; + + itsServerPort->send(echo); + itsFinished = true; + + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult tClient::test4(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Client@test4: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsClientPort = new GCFPort(*this, "SERVER:test4", + GCFPortInterface::SAP, ECHO_PROTOCOL); + ASSERTSTR(itsClientPort, "Failed to create a clientport in test4"); + LOG_INFO("Client:Starting test4"); + itsTimeoutTimer = itsClientPort->setTimer(30.0); // max duration of test + itsClientPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); + if ((timerEvent.id == itsTimeoutTimer) || + (timerEvent.id == itsFinishedTimer)) { + + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("CLIENT: TEST 4 FAILED ON TIMEOUT"); + gError |= 0x08; + } + itsClientPort->close(); // results in disconnected event + itsFinishedTimer = ~0; + break; + } + // 'open' timer expired, retry to open the client port. + if (!itsClientPort->isConnected()) { + itsClientPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsClientPort->isConnected()) { + // create PingEvent + timeval ping_time; + gettimeofday(&ping_time, 0); + + EchoPingEvent ping; + ping.seqnr = 4; + ping.ping_time = ping_time; + + // send the event + itsClientPort->send(ping); + LOG_INFO_STR("Client:PING sent (seqnr=" << ping.seqnr); + } + break; + + case F_DISCONNECTED: + port.close(); + case F_CLOSED: + if (itsFinishedTimer) { + LOG_INFO ("Client:Lost connection with server"); + finishTest(4); + TRAN(tClient::test5); + } + else { + itsClientPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_ECHO: { + EchoEchoEvent echo(event); + LOG_INFO_STR("client:ECHO received, seqnr=" << echo.seqnr); + itsFinishedTimer = itsClientPort->setTimer(0.5); + } + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +// +// TEST5 +// +// The server opens a TCP port with name "SERVER%s:test5" without using the +// configuration files, using instancenr 5. +// The client does the same. +// +GCFEvent::TResult tServer::test5(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Server@test5: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsServerPort = new GCFPort(*this, "SERVER%s:test5", + GCFPortInterface::SPP, ECHO_PROTOCOL); + ASSERTSTR(itsServerPort, "Failed to open serverport in test5"); LOG_INFO("Server:Starting test5"); + itsTimeoutTimer = itsServerPort->setTimer(30.0); // max duration of test + itsServerPort->setInstanceNr(5); + itsServerPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent = static_cast<GCFTimerEvent&>(event); + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("SERVER: TEST 5 FAILED ON TIMEOUT"); + gError |= 0x10; + itsServerPort->close(); // results in disconnected event + itsFinished = true; + break; + } + // 'open' timer expired, retry to open the server port. + if (!itsServerPort->isConnected()) { + itsServerPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsServerPort->isConnected()) { + // Alright, the server port is open wait for client or + // max testtime timer. + } + break; + + case F_CLOSED: + case F_DISCONNECTED: + if (itsFinished) { // timer exists when msg was received. + finishTest(5); + GCFTask::stop(); +// TRAN(tServer::test3); + } + else { + itsServerPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_PING: { + EchoPingEvent ping(event); + LOG_INFO_STR ("Server:PING received, seqnr=" << ping.seqnr); + + // Construct echo message and send it. + timeval echo_time; + gettimeofday(&echo_time, 0); + EchoEchoEvent echo; + echo.seqnr = ping.seqnr; + echo.ping_time = ping.ping_time; + echo.echo_time = echo_time; + + itsServerPort->send(echo); + itsFinished = true; + + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult tClient::test5(GCFEvent& event, GCFPortInterface& port) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("Client@test5: " << evtstr(event.signal)); + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: + itsClientPort = new GCFPort(*this, "SERVER%s:test5", + GCFPortInterface::SAP, ECHO_PROTOCOL); + ASSERTSTR(itsClientPort, "Failed to create a clientport in test5"); + LOG_INFO("Client:Starting test5"); + itsTimeoutTimer = itsClientPort->setTimer(30.0); // max duration of test + itsClientPort->setInstanceNr(5); + itsClientPort->open(); + break; + + case F_TIMER: { + // Max testtime reached? Force transition to next test. + GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); + if ((timerEvent.id == itsTimeoutTimer) || + (timerEvent.id == itsFinishedTimer)) { + + if (timerEvent.id == itsTimeoutTimer) { + LOG_WARN("CLIENT: TEST 5 FAILED ON TIMEOUT"); + gError |= 0x10; + } + itsClientPort->close(); // results in disconnected event + itsFinishedTimer = ~0; + break; + } + // 'open' timer expired, retry to open the client port. + if (!itsClientPort->isConnected()) { + itsClientPort->open(); + } + } + break; + + case F_CONNECTED: + if (itsClientPort->isConnected()) { + // create PingEvent + timeval ping_time; + gettimeofday(&ping_time, 0); + + EchoPingEvent ping; + ping.seqnr = 5; + ping.ping_time = ping_time; + + // send the event + itsClientPort->send(ping); + LOG_INFO_STR("Client:PING sent (seqnr=" << ping.seqnr); + } + break; + + case F_DISCONNECTED: + port.close(); + case F_CLOSED: + if (itsFinishedTimer) { + LOG_INFO ("Client:Lost connection with server"); + finishTest(5); + GCFTask::stop(); +// TRAN(tClient::test3); + } + else { + itsClientPort->setTimer(1.0); // try again after 1 second + } + break; + + case ECHO_ECHO: { + EchoEchoEvent echo(event); + LOG_INFO_STR("client:ECHO received, seqnr=" << echo.seqnr); + itsFinishedTimer = itsClientPort->setTimer(0.5); + } + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + + + + + } // namespace TM + } // namespace GCF +} // namespace LOFAR + +using namespace LOFAR::GCF::TM; + +// +// MAIN() +// +int main(int argc, char* argv[]) +{ + GCFTask::init(argc, argv); + + tServer serverTask("SERVER"); + tClient clientTask("CLIENT"); + + serverTask.start(); // make initial transition + clientTask.start(); // make initial transition + + GCFTask::run(); + + LOG_INFO_STR("Test result=" << gError); + + return (gError); +} diff --git a/MAC/GCF/TM/test/tGCFPort.conf b/MAC/GCF/TM/test/tGCFPort.conf new file mode 100644 index 0000000000000000000000000000000000000000..649c299b5457c0f8236354f389fa2fcecd03de50 --- /dev/null +++ b/MAC/GCF/TM/test/tGCFPort.conf @@ -0,0 +1,4 @@ +# test 1 +mac.ns.SERVER.test1.type=TCP +mac.top.CLIENT.1stTest.remoteservice=SERVER:test1 +mac.top.CLIENT.3rdTest.remoteservice=SERVER:test3 diff --git a/MAC/GCF/TM/test/tGCFPort.h b/MAC/GCF/TM/test/tGCFPort.h new file mode 100644 index 0000000000000000000000000000000000000000..3a434d19fe63456929da09f6e8e780581b97ee96 --- /dev/null +++ b/MAC/GCF/TM/test/tGCFPort.h @@ -0,0 +1,89 @@ +// +// tGCFPort.h: Test program to test all kind of usage of the GCF ports. +// +// 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 _TGCFPORT_H +#define _TGCFPORT_H + +#include <GCF/TM/GCF_Control.h> + +namespace LOFAR { + namespace GCF { + namespace TM { + +// +// The tests use two different tasks, a tServer task and a tClient task. +// In each test a different way of resolving the addresses is used or +// different device types are used. +// The tServer and tClient class use the Echo protocol to test the +// communication. +// + +static int32 gError; // used for synchronisation + +class tServer : public GCFTask +{ +public: + tServer (string name); + + // The test states + GCFEvent::TResult test1 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test2 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test3 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test4 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test5 (GCFEvent& e, GCFPortInterface& p); + +private: + void finishTest(uint32 testnr); + + GCFPort* itsServerPort; + uint32 itsTimeoutTimer; + bool itsFinished; +}; + +class tClient : public GCFTask +{ +public: + tClient (string name); + + // The test states + GCFEvent::TResult test1 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test2 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test3 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test4 (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult test5 (GCFEvent& e, GCFPortInterface& p); + + + +private: + void finishTest(uint32 testnr); + + GCFPort* itsClientPort; + uint32 itsTimeoutTimer; + uint32 itsFinishedTimer; +}; + + } // namespace TM + } // namespace GCF +} // namespace LOFAR +#endif diff --git a/MAC/GCF/_PAL/PA/src/GPA_Controller.cc b/MAC/GCF/_PAL/PA/src/GPA_Controller.cc index 7377300b224af227874d692f59dc30a738e35ee0..a696a78ff6f30ed19071d39f5a342706f8e1265d 100644 --- a/MAC/GCF/_PAL/PA/src/GPA_Controller.cc +++ b/MAC/GCF/_PAL/PA/src/GPA_Controller.cc @@ -27,7 +27,6 @@ #include <stdio.h> #include <GCF/Protocols/PA_Protocol.ph> #include <GCF/PAL/GCF_PVSSInfo.h> -#include <GCF/ParameterSet.h> namespace LOFAR { diff --git a/MAC/GCF/_PAL/PA/src/GPA_Converter.cc b/MAC/GCF/_PAL/PA/src/GPA_Converter.cc index 1f1f12b269937b580ec5396db96108cd01ebc00c..144ae245c0b4e1fa333a489ebc5c09b95aae6922 100644 --- a/MAC/GCF/_PAL/PA/src/GPA_Converter.cc +++ b/MAC/GCF/_PAL/PA/src/GPA_Converter.cc @@ -24,7 +24,7 @@ bool GPAConverter::uimMsgToGCFEvent(unsigned char* pMsgBuf, unsigned int length, string msg((char*) pMsgBuf, length); list<string> msgItems; - Utils::convStringToList(msgItems, msg); + Common::convStringToList(msgItems, msg); if (msgItems.size() < 5) return false; list<string>::iterator curMsgItem = msgItems.begin(); @@ -151,7 +151,7 @@ bool GPAConverter::gcfEventToUIMMsg(GCFPVBlob& gcfEvent, GCFPVBlob& uimMsg) break; } string uimMsgString; - Utils::convListToString(uimMsgString, uimMsgItems); + Common::convListToString(uimMsgString, uimMsgItems); uimMsg.setValue(uimMsgString); return true; } diff --git a/MAC/GCF/_PAL/PA/src/gcf-pa.conf.in b/MAC/GCF/_PAL/PA/src/gcf-pa.conf.in index 08a6e6482b557a1129341ef7c4009dcc1d4c96d1..457212a1b3bcf386acd376ec2b92c3cd3850b96b 100644 --- a/MAC/GCF/_PAL/PA/src/gcf-pa.conf.in +++ b/MAC/GCF/_PAL/PA/src/gcf-pa.conf.in @@ -1 +1 @@ -mac.ns.GCF-PA.provider.type=TCP \ No newline at end of file +#mac.ns.GCF-PA.provider.type=TCP diff --git a/MAC/GCF/_PAL/PI/src/GPI_Controller.cc b/MAC/GCF/_PAL/PI/src/GPI_Controller.cc index bcc87458435b8b6efef9eea7528d9c588a4c8221..cb2073fcc4c93b509f79a31c427593954cccecde 100644 --- a/MAC/GCF/_PAL/PI/src/GPI_Controller.cc +++ b/MAC/GCF/_PAL/PI/src/GPI_Controller.cc @@ -26,7 +26,7 @@ #include "GPI_CEPServer.h" #include "GPI_RTCServer.h" #include <GCF/Protocols/PI_Protocol.ph> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> namespace LOFAR { @@ -44,7 +44,7 @@ GPIController::GPIController() : // initialize the port provider _rtcClientPortProvider.init(*this, "rtc-provider", GCFPortInterface::MSPP, PI_PROTOCOL); _cepClientPortProvider.init(*this, "cep-provider", GCFPortInterface::MSPP, PI_PROTOCOL); - ParameterSet::instance()->adoptFile("PropertyAgent.conf"); + ACC::APS::globalParameterSet()->adoptFile("PropertyAgent.conf"); } GPIController::~GPIController() diff --git a/MAC/GCF/_PAL/PI/src/GPI_PropertySet.cc b/MAC/GCF/_PAL/PI/src/GPI_PropertySet.cc index 4a6c1a503ed38a26653eb32f369b953bc6fc87e9..d0f4d1f5f833da909b17eb56a0907b4cd538e5c1 100644 --- a/MAC/GCF/_PAL/PI/src/GPI_PropertySet.cc +++ b/MAC/GCF/_PAL/PI/src/GPI_PropertySet.cc @@ -281,7 +281,7 @@ bool GPIPropertySet::propSetLinkedInClient(const PIPropSetLinkedEvent& responseI _state = S_LINKING; if (responseIn.result != PI_PS_GONE) { - Utils::convStringToList(_propsSubscribed, responseIn.propList); + Common::convStringToList(_propsSubscribed, responseIn.propList); _tmpPIResult = responseIn.result; return trySubscribing(); } diff --git a/MAC/GCF/_PAL/PML/src/GCF_PropertySet.cc b/MAC/GCF/_PAL/PML/src/GCF_PropertySet.cc index d17d577d209bb83fa8637ec3b23916cbee48716d..e7940fc5e7ba3cf78f0c8a6b16aac526eb653d1a 100644 --- a/MAC/GCF/_PAL/PML/src/GCF_PropertySet.cc +++ b/MAC/GCF/_PAL/PML/src/GCF_PropertySet.cc @@ -51,7 +51,7 @@ GCFPropertySet::GCFPropertySet (const char* name, _dummyProperty(dummyPropInfo, this), _isBusy(false) { - if (!Utils::isValidScope(_scope.c_str())) + if (!Common::isValidScope(_scope.c_str())) { LOG_WARN(LOFAR::formatString ( "Scope %s meets not the name convention! Set to \"\"", diff --git a/MAC/GCF/_PAL/PML/src/GPM_Controller.cc b/MAC/GCF/_PAL/PML/src/GPM_Controller.cc index ab989320469e5dc743bb0b1c3147e06e4335c7a6..3ea347880e132e7ada004fdf5a14e9e3aacc399b 100644 --- a/MAC/GCF/_PAL/PML/src/GPM_Controller.cc +++ b/MAC/GCF/_PAL/PML/src/GPM_Controller.cc @@ -21,50 +21,60 @@ //# $Id$ #include <lofar_config.h> +#include <Common/LofarLocators.h> #include "GPM_Controller.h" #include <GCF/PAL/GCF_ExtPropertySet.h> #include <GCF/PAL/GCF_MyPropertySet.h> #include <GCF/PAL/GCF_SysConnGuard.h> #include <GCF/Utils.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> #include <GCF/PAL/GCF_PVSSInfo.h> #include <stdio.h> -namespace LOFAR -{ - namespace GCF - { -using namespace Common; -using namespace TM; - namespace PAL - { -static string sPMLTaskName("GCF-PML"); -GPMHandler* GPMHandler::_pInstance = 0; +namespace LOFAR { + namespace GCF { + using namespace Common; + using namespace TM; + namespace PAL { + +static string sPMLTaskName("GCF-PML"); +GPMHandler* GPMHandler::_pInstance = 0; void logResult(TPAResult result, GCFPropertySet& propSet); -GPMController::GPMController() : - GCFTask((State)&GPMController::initial, sPMLTaskName), - _pSysConnGuard(GCFSysConnGuard::instance()) +// +// GPMController +// +GPMController::GPMController() : + GCFTask((State)&GPMController::initial, sPMLTaskName), + _pSysConnGuard(GCFSysConnGuard::instance()) { - // register the protocol for debugging purposes - registerProtocol(PA_PROTOCOL, PA_PROTOCOL_signalnames); + // register the protocol for debugging purposes + registerProtocol(PA_PROTOCOL, PA_PROTOCOL_signalnames); - // initialize the port - _propertyAgent.init(*this, "client", GCFPortInterface::SAP, PA_PROTOCOL); + // initialize the port + _propertyAgent.init(*this, "client", GCFPortInterface::SAP, PA_PROTOCOL); - _distPropertyAgent.init(*this, "DPAclient", GCFPortInterface::SAP, PA_PROTOCOL); - - ParameterSet::instance()->adoptFile("gcf-pml.conf"); - ParameterSet::instance()->adoptFile("PropertyAgent.conf"); - _pSysConnGuard->registerTask(*this); + _distPropertyAgent.init(*this, "DPAclient", GCFPortInterface::SAP, PA_PROTOCOL); + + // read in the configuration files. + ConfigLocator aCL; + LOG_DEBUG ("Adopting config file: gcf-pml.conf"); + ACC::APS::globalParameterSet()->adoptFile(aCL.locate("gcf-pml.conf")); + LOG_DEBUG ("Adopting config file: PropertyAgent.conf"); + ACC::APS::globalParameterSet()->adoptFile(aCL.locate("PropertyAgent.conf")); + + _pSysConnGuard->registerTask(*this); } +// +// ~GPMController +// GPMController::~GPMController() { - _pSysConnGuard->unregisterTask(*this); + _pSysConnGuard->unregisterTask(*this); } GPMController* GPMController::instance(bool temporary) diff --git a/MAC/GCF/_PAL/SAL/src/GCF_PVSSInfo.cc b/MAC/GCF/_PAL/SAL/src/GCF_PVSSInfo.cc index 0c0324558fa7025ddfeab948c603f342cc55f985..40dc274f26a6bd7db5a9ad8a9489b5d02fe71177 100644 --- a/MAC/GCF/_PAL/SAL/src/GCF_PVSSInfo.cc +++ b/MAC/GCF/_PAL/SAL/src/GCF_PVSSInfo.cc @@ -339,7 +339,7 @@ void buildTypeStructTree(const string path, { if (macValueTypes[elType] != NO_LPT) { - if (Utils::isValidPropName(propName.c_str())) + if (Common::isValidPropName(propName.c_str())) { TPropertyInfo propInfo; propInfo.propName = propName; diff --git a/MAC/GCF/_PAL/SAL/src/GCF_PVSSPort.cc b/MAC/GCF/_PAL/SAL/src/GCF_PVSSPort.cc index b0ec85789bdb02c693df887aaf05991bdd3d594a..6229134f0d325a040336c0bc3da5ea3797994584 100644 --- a/MAC/GCF/_PAL/SAL/src/GCF_PVSSPort.cc +++ b/MAC/GCF/_PAL/SAL/src/GCF_PVSSPort.cc @@ -46,11 +46,11 @@ static GCFEvent connectedEvent (F_CONNECTED); static GCFEvent closedEvent (F_CLOSED); GCFPVSSPort::TPVSSPortNrs GCFPVSSPort::_pvssPortNrs; -GCFPVSSPort::GCFPVSSPort(GCFTask& task, - string name, - TPortType type, - int protocol, - bool transportRawData) +GCFPVSSPort::GCFPVSSPort(GCFTask& task, + const string& name, + TPortType type, + int protocol, + bool transportRawData) : GCFRawPort(task, name, type, protocol, transportRawData), _pPortService(0), _acceptedPort(false) diff --git a/MAC/GCF/_PAL/SAL/src/GSA_SCADAHandler.cc b/MAC/GCF/_PAL/SAL/src/GSA_SCADAHandler.cc index db727589416d8e62b5ca05eb3a74ac383f3f2385..6bd8a4794e5a513a9121a590fc0afea2ba9c229e 100644 --- a/MAC/GCF/_PAL/SAL/src/GSA_SCADAHandler.cc +++ b/MAC/GCF/_PAL/SAL/src/GSA_SCADAHandler.cc @@ -30,7 +30,7 @@ #include "GSA_SCADAHandler.h" #include <GSA_Resources.h> #include <GCF/TM/GCF_Task.h> -#include <GCF/ParameterSet.h> +#include <APS/ParameterSet.h> namespace LOFAR { @@ -53,13 +53,13 @@ GSASCADAHandler* GSASCADAHandler::instance() cmdline += "-currentproj "; string pvssCmdLineParam = PARAM_DEFAULT_PVSS_CMDLINE; char* appName = strrchr(GCFTask::_argv[0], '/'); - if (!ParameterSet::instance()->isDefined(pvssCmdLineParam)) + if (!ACC::APS::globalParameterSet()->isDefined(pvssCmdLineParam)) { pvssCmdLineParam = formatString(PARAM_PVSS_CMDLINE, (appName ? appName + 1 : GCFTask::_argv[0])); } - if (ParameterSet::instance()->isDefined(pvssCmdLineParam)) + if (ACC::APS::globalParameterSet()->isDefined(pvssCmdLineParam)) { - cmdline += ParameterSet::instance()->getString(pvssCmdLineParam); + cmdline += ACC::APS::globalParameterSet()->getString(pvssCmdLineParam); } // The PVSS API 3.0.1 redirects stdout and stderr output automatically to // a file created by the API diff --git a/MAC/GCF/_PAL/configure.in b/MAC/GCF/_PAL/configure.in index 930d8e67e5a499a2488d3285b58c3f354712d21f..c65e68f478c0694304c26b0e68f94887d1991a89 100644 --- a/MAC/GCF/_PAL/configure.in +++ b/MAC/GCF/_PAL/configure.in @@ -39,11 +39,12 @@ lofar_GENERAL lofar_PVSS(1) lofar_INTERNAL(LCS/Common, common, LCS-Common-2_3, 1, Common/LofarTypes.h,,) lofar_INTERNAL(LCS/Transport, transport, LCS-Transport-2_1, 1, Transport/DataHolder.h,,) -lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, MAC-GCF-6_2, 1, GCF/GCF_Defines.h,,) -lofar_INTERNAL(MAC/GCF/TM, gcftm, MAC-GCF-6_2, 1, GCF/TM/GCF_Task.h,,) -lofar_INTERNAL(MAC/GCF/Protocols, gcfpirtcprot, MAC-GCF-6_2, 1, GCF/Protocols/PI_Protocol.ph,,) -lofar_INTERNAL(MAC/GCF/Protocols, gcfpicepprot, MAC-GCF-6_2, 1, GCF/Protocols/DH_PIProtocol.h,,) -lofar_INTERNAL(MAC/GCF/Protocols, gcfpaprot, MAC-GCF-6_2, 1, GCF/Protocols/PA_Protocol.ph,,) +lofar_INTERNAL(LCS/ACC/APS, APS, ,1, APS/ParameterSet.h,,) +lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, , 1, GCF/GCF_Defines.h,,) +lofar_INTERNAL(MAC/GCF/TM, gcftm, , 1, GCF/TM/GCF_Task.h,,) +lofar_INTERNAL(MAC/GCF/Protocols, gcfpirtcprot, , 1, GCF/Protocols/PI_Protocol.ph,,) +lofar_INTERNAL(MAC/GCF/Protocols, gcfpicepprot, , 1, GCF/Protocols/DH_PIProtocol.h,,) +lofar_INTERNAL(MAC/GCF/Protocols, gcfpaprot, , 1, GCF/Protocols/PA_Protocol.ph,,) dnl dnl Output Makefiles diff --git a/MAC/GCF/_PAL/include/GCF/PAL/GCF_PVSSPort.h b/MAC/GCF/_PAL/include/GCF/PAL/GCF_PVSSPort.h index 724caa55bcc33400cad7967654e3a36db07a32e8..1badcc5e160e57ba555f836e17465966c9280264 100644 --- a/MAC/GCF/_PAL/include/GCF/PAL/GCF_PVSSPort.h +++ b/MAC/GCF/_PAL/include/GCF/PAL/GCF_PVSSPort.h @@ -61,11 +61,11 @@ class GCFPVSSPort : public TM::GCFRawPort // Construction methods // @param protocol NOT USED - explicit GCFPVSSPort (TM::GCFTask& task, - string name, - TM::GCFPortInterface::TPortType type, - int protocol, - bool transportRawData = false); + explicit GCFPVSSPort (TM::GCFTask& task, + const string& name, + TM::GCFPortInterface::TPortType type, + int protocol, + bool transportRawData = false); explicit GCFPVSSPort ();