diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/LogicalDevice.h b/MAC/APL/APLCommon/include/APL/APLCommon/LogicalDevice.h index e42ccef33a8aebf4d59a9b1ff39a576ae89143de..b7dc9192fc444d98d4fef5e5c3ce6c004f8956ed 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/LogicalDevice.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/LogicalDevice.h @@ -157,7 +157,7 @@ namespace APLCommon virtual ::GCFEvent::TResult concrete_idle_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; virtual ::GCFEvent::TResult concrete_claiming_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; virtual ::GCFEvent::TResult concrete_preparing_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; - virtual ::GCFEvent::TResult concrete_active_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; + virtual ::GCFEvent::TResult concrete_active_state(::GCFEvent& e, ::GCFPortInterface& p)=0; virtual ::GCFEvent::TResult concrete_releasing_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; virtual void concreteClaim(::GCFPortInterface& port)=0; @@ -167,6 +167,8 @@ namespace APLCommon virtual void concreteRelease(::GCFPortInterface& port)=0; virtual void concreteParentDisconnected(::GCFPortInterface& port)=0; virtual void concreteChildDisconnected(::GCFPortInterface& port)=0; + virtual void concreteHandleTimers(::GCFTimerEvent& timerEvent, ::GCFPortInterface& port)=0; + protected: APL_DECLARE_SHARED_POINTER(GCFMyPropertySet) @@ -175,6 +177,9 @@ namespace APLCommon GCFMyPropertySetSharedPtr m_propertySet; ACC::ParameterSet m_parameterSet; + string m_serverPortName; + TRemotePort m_serverPort; // listening port + private: void _schedule(); void _cancelSchedule(); @@ -201,9 +206,7 @@ namespace APLCommon typedef map<string,TPortSharedPtr> TPortMap; typedef vector<TBufferedEventInfo> TEventBufferVector; - string m_serverPortName; TRemotePort m_parentPort; // connection with parent, if any - TRemotePort m_serverPort; // listening port // 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, diff --git a/MAC/APL/APLCommon/include/APLCommon/LogicalDevice.h b/MAC/APL/APLCommon/include/APLCommon/LogicalDevice.h index e42ccef33a8aebf4d59a9b1ff39a576ae89143de..b7dc9192fc444d98d4fef5e5c3ce6c004f8956ed 100644 --- a/MAC/APL/APLCommon/include/APLCommon/LogicalDevice.h +++ b/MAC/APL/APLCommon/include/APLCommon/LogicalDevice.h @@ -157,7 +157,7 @@ namespace APLCommon virtual ::GCFEvent::TResult concrete_idle_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; virtual ::GCFEvent::TResult concrete_claiming_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; virtual ::GCFEvent::TResult concrete_preparing_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; - virtual ::GCFEvent::TResult concrete_active_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; + virtual ::GCFEvent::TResult concrete_active_state(::GCFEvent& e, ::GCFPortInterface& p)=0; virtual ::GCFEvent::TResult concrete_releasing_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState)=0; virtual void concreteClaim(::GCFPortInterface& port)=0; @@ -167,6 +167,8 @@ namespace APLCommon virtual void concreteRelease(::GCFPortInterface& port)=0; virtual void concreteParentDisconnected(::GCFPortInterface& port)=0; virtual void concreteChildDisconnected(::GCFPortInterface& port)=0; + virtual void concreteHandleTimers(::GCFTimerEvent& timerEvent, ::GCFPortInterface& port)=0; + protected: APL_DECLARE_SHARED_POINTER(GCFMyPropertySet) @@ -175,6 +177,9 @@ namespace APLCommon GCFMyPropertySetSharedPtr m_propertySet; ACC::ParameterSet m_parameterSet; + string m_serverPortName; + TRemotePort m_serverPort; // listening port + private: void _schedule(); void _cancelSchedule(); @@ -201,9 +206,7 @@ namespace APLCommon typedef map<string,TPortSharedPtr> TPortMap; typedef vector<TBufferedEventInfo> TEventBufferVector; - string m_serverPortName; TRemotePort m_parentPort; // connection with parent, if any - TRemotePort m_serverPort; // listening port // 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, diff --git a/MAC/APL/APLCommon/src/LogicalDevice.cc b/MAC/APL/APLCommon/src/LogicalDevice.cc index 1ba4e87e50611114d767252db75a64b8bbb94c9e..9f5f97e1c4c9cb92815a066a278991ac0e84abe5 100644 --- a/MAC/APL/APLCommon/src/LogicalDevice.cc +++ b/MAC/APL/APLCommon/src/LogicalDevice.cc @@ -75,8 +75,8 @@ LogicalDevice::LogicalDevice(const string& taskName, const string& parameterFile m_propertySet(), m_parameterSet(), m_serverPortName(string("server")), - m_parentPort(), m_serverPort(*this, m_serverPortName, ::GCFPortInterface::MSPP, LOGICALDEVICE_PROTOCOL), + m_parentPort(), m_childPorts(), m_connectedChildPorts(), m_childStartDaemonPorts(), @@ -356,6 +356,13 @@ time_t LogicalDevice::_decodeTimeParameter(const string& timeStr) const void LogicalDevice::_schedule() { + LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,getName().c_str()); + if(m_prepareTimerId != 0) + m_serverPort.cancelTimer(m_prepareTimerId); + if(m_startTimerId != 0) + m_serverPort.cancelTimer(m_startTimerId); + if(m_stopTimerId != 0) + m_serverPort.cancelTimer(m_stopTimerId); // // set timers // specified times are in UTC, seconds since 1-1-1970 @@ -373,6 +380,7 @@ void LogicalDevice::_schedule() void LogicalDevice::_cancelSchedule() { + LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,getName().c_str()); m_serverPort.cancelTimer(m_prepareTimerId); m_serverPort.cancelTimer(m_startTimerId); m_serverPort.cancelTimer(m_stopTimerId); @@ -381,7 +389,7 @@ void LogicalDevice::_cancelSchedule() LOGICALDEVICECancelscheduleEvent cancelEvent; _sendToAllChilds(cancelEvent); - _suspend(); + _release(); } void LogicalDevice::_claim() @@ -534,6 +542,7 @@ void LogicalDevice::_doStateTransition(const TLogicalDeviceState& newState) void LogicalDevice::_handleTimers(::GCFEvent& event, ::GCFPortInterface& port) { + LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,formatString("%s - event=%s",getName().c_str(),evtstr(event)).c_str()); if(event.signal == F_TIMER) { GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); @@ -608,6 +617,10 @@ void LogicalDevice::_handleTimers(::GCFEvent& event, ::GCFPortInterface& port) // keep on polling m_retrySendTimerId = m_serverPort.setTimer(static_cast<long int>(retryPeriod)); } + else + { + concreteHandleTimers(timerEvent,port); + } } } @@ -893,11 +906,43 @@ string LogicalDevice::_getShareLocation() const break; } + case LOGICALDEVICE_SCHEDULE: + { + LOGICALDEVICEScheduleEvent scheduleEvent(event); + m_parameterSet.adoptFile(_getShareLocation() + string("share/") + scheduleEvent.fileName); + _schedule(); + + LOGICALDEVICEScheduledEvent scheduledEvent; + scheduledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduledEvent); + break; + } + + case LOGICALDEVICE_CANCELSCHEDULE: + { + _cancelSchedule(); + + LOGICALDEVICESchedulecancelledEvent scheduleCancelledEvent; + scheduleCancelledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduleCancelledEvent); + break; + } + case LOGICALDEVICE_CLAIM: TRAN(LogicalDevice::claiming_state); concreteClaim(port); break; + case LOGICALDEVICE_RELEASE: // release in idle state? at the moment necessary for old style VT + { + // send release event to childs + LOGICALDEVICEReleaseEvent releaseEvent; + _sendToAllChilds(releaseEvent); + TRAN(LogicalDevice::releasing_state); + concreteRelease(port); + break; + } + default: LOG_DEBUG(formatString("LogicalDevice(%s)::idle_state, default",getName().c_str())); status = ::GCFEvent::NOT_HANDLED; @@ -940,6 +985,26 @@ string LogicalDevice::_getShareLocation() const _handleTimers(event,port); break; + case LOGICALDEVICE_CANCELSCHEDULE: + { + _cancelSchedule(); + + LOGICALDEVICESchedulecancelledEvent scheduleCancelledEvent; + scheduleCancelledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduleCancelledEvent); + break; + } + + case LOGICALDEVICE_RELEASE: + { + // send release event to childs + LOGICALDEVICEReleaseEvent releaseEvent; + _sendToAllChilds(releaseEvent); + TRAN(LogicalDevice::releasing_state); + concreteRelease(port); + break; + } + // the LOGICALDEVICE_CLAIMED event cannot result in a transition to // the claimed state here, because the logical device may have several // children that all send their LOGICALDEVICE_CLAIMED message. @@ -989,6 +1054,28 @@ string LogicalDevice::_getShareLocation() const _handleTimers(event,port); break; + case LOGICALDEVICE_SCHEDULE: + { + LOGICALDEVICEScheduleEvent scheduleEvent(event); + m_parameterSet.adoptFile(_getShareLocation() + string("share/") + scheduleEvent.fileName); + _schedule(); + + LOGICALDEVICEScheduledEvent scheduledEvent; + scheduledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduledEvent); + break; + } + + case LOGICALDEVICE_CANCELSCHEDULE: + { + _cancelSchedule(); + + LOGICALDEVICESchedulecancelledEvent scheduleCancelledEvent; + scheduleCancelledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduleCancelledEvent); + break; + } + case LOGICALDEVICE_PREPARE: { TRAN(LogicalDevice::preparing_state); @@ -998,10 +1085,15 @@ string LogicalDevice::_getShareLocation() const } case LOGICALDEVICE_RELEASE: + { + // send release event to childs + LOGICALDEVICEReleaseEvent releaseEvent; + _sendToAllChilds(releaseEvent); TRAN(LogicalDevice::releasing_state); concreteRelease(port); break; - + } + default: LOG_DEBUG(formatString("LogicalDevice(%s)::claimed_state, default",getName().c_str())); status = ::GCFEvent::NOT_HANDLED; @@ -1044,6 +1136,26 @@ string LogicalDevice::_getShareLocation() const _handleTimers(event,port); break; + case LOGICALDEVICE_CANCELSCHEDULE: + { + _cancelSchedule(); + + LOGICALDEVICESchedulecancelledEvent scheduleCancelledEvent; + scheduleCancelledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduleCancelledEvent); + break; + } + + case LOGICALDEVICE_RELEASE: + { + // send release event to childs + LOGICALDEVICEReleaseEvent releaseEvent; + _sendToAllChilds(releaseEvent); + TRAN(LogicalDevice::releasing_state); + concreteRelease(port); + break; + } + // the LOGICALDEVICE_PREPARED event cannot result in a transition to // the suspended state here, because the logical device may have several // children that all send their LOGICALDEVICE_PREPARED message. @@ -1093,6 +1205,16 @@ string LogicalDevice::_getShareLocation() const _handleTimers(event,port); break; + case LOGICALDEVICE_CANCELSCHEDULE: + { + _cancelSchedule(); + + LOGICALDEVICESchedulecancelledEvent scheduleCancelledEvent; + scheduleCancelledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduleCancelledEvent); + break; + } + case LOGICALDEVICE_PREPARE: { TRAN(LogicalDevice::preparing_state); @@ -1115,9 +1237,8 @@ string LogicalDevice::_getShareLocation() const case LOGICALDEVICE_RELEASE: { // send release event to childs - LOGICALDEVICEResumeEvent releaseEvent; + LOGICALDEVICEReleaseEvent releaseEvent; _sendToAllChilds(releaseEvent); - TRAN(LogicalDevice::releasing_state); concreteRelease(port); break; @@ -1161,6 +1282,16 @@ string LogicalDevice::_getShareLocation() const _handleTimers(event,port); break; + case LOGICALDEVICE_CANCELSCHEDULE: + { + _cancelSchedule(); + + LOGICALDEVICESchedulecancelledEvent scheduleCancelledEvent; + scheduleCancelledEvent.result = LD_RESULT_NO_ERROR; + port.send(scheduleCancelledEvent); + break; + } + case LOGICALDEVICE_PREPARE: // invalid message in this state LOG_DEBUG(formatString("LogicalDevice(%s)::active_state, PREPARE NOT ALLOWED",getName().c_str())); @@ -1178,14 +1309,23 @@ string LogicalDevice::_getShareLocation() const break; } + case LOGICALDEVICE_RELEASE: + { + // send release event to childs + LOGICALDEVICEReleaseEvent releaseEvent; + _sendToAllChilds(releaseEvent); + TRAN(LogicalDevice::releasing_state); + concreteRelease(port); + break; + } + default: LOG_DEBUG(formatString("LogicalDevice(%s)::active_state, default",getName().c_str())); status = ::GCFEvent::NOT_HANDLED; break; } - TLogicalDeviceState newState=LOGICALDEVICE_STATE_NOSTATE; ::GCFEvent::TResult concreteStatus; - concreteStatus = concrete_active_state(event, port, newState); + concreteStatus = concrete_active_state(event, port); return (status==::GCFEvent::HANDLED||concreteStatus==::GCFEvent::HANDLED?::GCFEvent::HANDLED : ::GCFEvent::NOT_HANDLED); } diff --git a/MAC/APL/_GSO/MACScheduler/src/MACScheduler.cc b/MAC/APL/_GSO/MACScheduler/src/MACScheduler.cc index 8ad7540edc93552ce62e95d380712fb4b9b2332e..d5859cbf10880c3bc8de473250645e1ab3db4e50 100644 --- a/MAC/APL/_GSO/MACScheduler/src/MACScheduler.cc +++ b/MAC/APL/_GSO/MACScheduler/src/MACScheduler.cc @@ -445,15 +445,61 @@ string MACScheduler::_getShareLocation() const case F_DISCONNECTED: _disconnectedHandler(port); break; + + case SAS_SCHEDULE: + case SAS_CANCELSCHEDULE: + case SAS_UPDATESCHEDULE: + _handleSASprotocol(event,port); + break; + + case LOGICALDEVICE_CONNECT: + { + LOGICALDEVICEConnectEvent connectEvent(event); + TRemotePortPtr portPtr(static_cast<TRemotePort*>(&port)); + m_connectedVIclientPorts[connectEvent.nodeId] = portPtr; + + LOGICALDEVICEConnectedEvent connectedEvent; + connectedEvent.result = LD_RESULT_NO_ERROR; + port.send(connectedEvent); + break; + } + case LOGICALDEVICE_SCHEDULED: + { + LOGICALDEVICEScheduledEvent scheduledEvent(event); + m_propertySet->setValue(MS_PROPNAME_STATUS,GCFPVInteger(scheduledEvent.result)); + break; + } + + case LOGICALDEVICE_SCHEDULECANCELLED: + { + LOGICALDEVICESchedulecancelledEvent schedulecancelledEvent(event); + m_propertySet->setValue(MS_PROPNAME_STATUS,GCFPVInteger(schedulecancelledEvent.result)); + break; + } + + default: + LOG_DEBUG(formatString("MACScheduler(%s)::idle_state, default",getName().c_str())); + status = ::GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +void MACScheduler::_handleSASprotocol(::GCFEvent& event, ::GCFPortInterface& port) +{ + LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,formatString("%s - event=%s",getName().c_str(),evtstr(event)).c_str()); + + switch (event.signal) + { case SAS_SCHEDULE: { - string shareLocation = _getShareLocation(); - // schedule event received from SAS SASScheduleEvent sasScheduleEvent(event); SASResponseEvent sasResponseEvent; sasResponseEvent.result = SAS_RESULT_NO_ERROR; + string shareLocation = _getShareLocation(); try { @@ -499,33 +545,104 @@ string MACScheduler::_getShareLocation() const port.send(sasResponseEvent); break; } - - case LOGICALDEVICE_CONNECT: + case SAS_CANCELSCHEDULE: { - LOGICALDEVICEConnectEvent connectEvent(event); - TRemotePortPtr portPtr(static_cast<TRemotePort*>(&port)); - m_connectedVIclientPorts[connectEvent.nodeId] = portPtr; + // schedule event received from SAS + SASCancelscheduleEvent sasCancelScheduleEvent(event); + SASResponseEvent sasResponseEvent; + sasResponseEvent.result = SAS_RESULT_NO_ERROR; + string shareLocation = _getShareLocation(); - LOGICALDEVICEConnectedEvent connectedEvent; - connectedEvent.result = LD_RESULT_NO_ERROR; - port.send(connectedEvent); + // search the port of the VI + try + { + // read the parameterset from the database: +#ifndef ACC_CONFIGURATIONMGR_UNAVAILABLE + boost::shared_ptr<ACC::ParameterSet> ps(m_configurationManager->getPS(sasCancelScheduleEvent.VIrootID, "latest"); +#else // ACC_CONFIGURATIONMGR_UNAVAILABLE + LOG_FATAL("TODO: Use ACC::ConfigurationMgr to access OTDB database"); + // When the ACC::ConfigurationMgr can be used, then the following code is obsolete: + ACC::ParameterCollection pc(shareLocation + string("share/") + sasCancelScheduleEvent.VIrootID); // assume VIrootID is a file + boost::shared_ptr<ACC::ParameterSet> ps(new ACC::ParameterSet(pc)); + // End of soon to be obsolete code +#endif // ACC_CONFIGURATIONMGR_UNAVAILABLE + + string viName = ps->getString("name"); + + // send a CANCELSCHEDULE message + TStringRemotePortMap::iterator it = m_connectedVIclientPorts.find(viName); + if(it != m_connectedVIclientPorts.end()) + { + LOGICALDEVICECancelscheduleEvent cancelScheduleEvent; + it->second->send(cancelScheduleEvent); + } + else + { + sasResponseEvent.result = SAS_RESULT_ERROR_VI_NOT_FOUND; + } + } + catch(Exception& e) + { + LOG_FATAL(formatString("Error reading schedule parameters: %s",e.message().c_str())); + sasResponseEvent.result = SAS_RESULT_ERROR_UNSPECIFIED; + } + port.send(sasResponseEvent); break; } - case LOGICALDEVICE_SCHEDULED: + case SAS_UPDATESCHEDULE: { - LOGICALDEVICEScheduledEvent scheduledEvent(event); - m_propertySet->setValue(MS_PROPNAME_STATUS,GCFPVInteger(scheduledEvent.result)); + // schedule event received from SAS + SASUpdatescheduleEvent sasUpdateScheduleEvent(event); + SASResponseEvent sasResponseEvent; + sasResponseEvent.result = SAS_RESULT_NO_ERROR; + string shareLocation = _getShareLocation(); + + // search the port of the VI + try + { + // read the parameterset from the database: +#ifndef ACC_CONFIGURATIONMGR_UNAVAILABLE + boost::shared_ptr<ACC::ParameterSet> ps(m_configurationManager->getPS(sasUpdateScheduleEvent.VIrootID, "latest"); +#else // ACC_CONFIGURATIONMGR_UNAVAILABLE + LOG_FATAL("TODO: Use ACC::ConfigurationMgr to access OTDB database"); + // When the ACC::ConfigurationMgr can be used, then the following code is obsolete: + ACC::ParameterCollection pc(shareLocation + string("share/") + sasUpdateScheduleEvent.VIrootID); // assume VIrootID is a file + boost::shared_ptr<ACC::ParameterSet> ps(new ACC::ParameterSet(pc)); + // End of soon to be obsolete code +#endif // ACC_CONFIGURATIONMGR_UNAVAILABLE + + string allocatedCCU = ps->getString("allocatedCCU"); + string viName = ps->getString("name"); + string psFileName = string("/") + viName + string(".ps"); + string psFilePath = shareLocation + string("mnt/") + allocatedCCU + string("/") + psFileName; + ps->writeFile(psFilePath); + + // send a SCHEDULE message + TStringRemotePortMap::iterator it = m_connectedVIclientPorts.find(viName); + if(it != m_connectedVIclientPorts.end()) + { + LOGICALDEVICEScheduleEvent scheduleEvent; + scheduleEvent.fileName = psFileName; + it->second->send(scheduleEvent); + } + else + { + sasResponseEvent.result = SAS_RESULT_ERROR_VI_NOT_FOUND; + } + } + catch(Exception& e) + { + LOG_FATAL(formatString("Error reading schedule parameters: %s",e.message().c_str())); + sasResponseEvent.result = SAS_RESULT_ERROR_UNSPECIFIED; + } + port.send(sasResponseEvent); break; } - + default: - LOG_DEBUG(formatString("MACScheduler(%s)::idle_state, default",getName().c_str())); - status = ::GCFEvent::NOT_HANDLED; break; } - - return status; } diff --git a/MAC/APL/_GSO/MACScheduler/src/MACScheduler.h b/MAC/APL/_GSO/MACScheduler/src/MACScheduler.h index 2654b69ed70d5fdc32bcb21db2e663d02ec7c08b..c6fa9f81e6ad96d7042f1af76d4b3a37e825b45d 100644 --- a/MAC/APL/_GSO/MACScheduler/src/MACScheduler.h +++ b/MAC/APL/_GSO/MACScheduler/src/MACScheduler.h @@ -133,6 +133,7 @@ namespace GSO bool _isVISDclientPort(const ::GCFPortInterface& port, string& visd) const; bool _isVIclientPort(const ::GCFPortInterface& port) const; string _getShareLocation() const; + void _handleSASprotocol(::GCFEvent& event, ::GCFPortInterface& port); string m_SASserverPortName; GCFTCPPort m_SASserverPort; // SAS-MAC communication diff --git a/MAC/APL/_GSO/MACScheduler/src/MACScheduler.log_prop.in b/MAC/APL/_GSO/MACScheduler/src/MACScheduler.log_prop.in index 662e822497e4f9fd82480902bad49762b47cd60f..43a7f948f3a6f5b8f66140a11b28b42eb7536db3 100644 --- a/MAC/APL/_GSO/MACScheduler/src/MACScheduler.log_prop.in +++ b/MAC/APL/_GSO/MACScheduler/src/MACScheduler.log_prop.in @@ -17,6 +17,12 @@ log4cplus.appender.PUTJE=log4cplus::NullAppender log4cplus.appender.STDOUT=log4cplus::ConsoleAppender log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout log4cplus.appender.STDOUT.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S} %-5p %c{9} - %m [%.25l]%n +#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=MACScheduler.log diff --git a/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.btsw b/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.btsw index 7c457eaa23c87e94ee23bd61192fb2a0ce3b2e9f..781c49b8b2e7b82617b43a55bed5ee403c108299 100644 --- a/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.btsw +++ b/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.btsw @@ -14,66 +14,74 @@ [statemachines] -Statemachine_MACScheduler (ready, time_is_over) = +Statemachine_MACScheduler (ready, stopBeamServer, bs_alloc_ack, bs_pointto_ack) = { -VAR a= 0x00000001, b. - s000 : SAS_SCHEDULE ( "VI1.ps" ) ; s010. - - s010 : SAS_RESPONSE ( 0x00000000 ) ; s910. // scheduled ok + s010 : SAS_RESPONSE ( 0x00000000 ) ; s020. + s020 : R_SIG ( bs_alloc_ack ) ; s100. + s020 : TIMER(30) ; timeout. + + s100 : SAS_CANCELSCHEDULE ( "VI1.ps" ) ; s110. + s110 : SAS_RESPONSE ( 0x00000000 ) ; s200. + s200 : SAS_SCHEDULE ( "VI2.ps" ) ; s210. + s210 : SAS_RESPONSE ( 0x00000000 ) ; s220. + s220 : R_SIG ( bs_alloc_ack ) ; s300. + s220 : TIMER(30) ; timeout. -// s900 : R_SIG (time_is_over) ; s910. -// s900 : TIMER (0x1) ; s000. // Re-run after one second + s300 : SAS_UPDATESCHEDULE ( "VI1.ps" ) ; s310. + s310 : SAS_RESPONSE ( 0x00000000 ) ; s320. + s320 : R_SIG ( bs_alloc_ack ) ; finish. + s320 : TIMER(30) ; timeout. - s910 : S_SIG (ready ) ; OK. - OK : TIMER(10) ; OK. + finish : S_SIG ( ready ) + S_SIG ( stopBeamServer ) ; OK. + OK : TIMER(60) ; OK. + + timeout : TERMINATE ; timeout. + error : TERMINATE ; error. } -Statemachine_BeamServer (ready, time_is_over) = +Statemachine_BeamServer ( stop, bs_alloc_ack, bs_pointto_ack ) = { VAR handle. - s000 : ABS_BEAMALLOC (, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,) ; s010. + s000 : ABS_BEAMALLOC (, ,,,,,,,,,, ,,,,,,,,,, + ,,,,,,,,,, ,,,,,,,,,, + ,,,,,,,,,, ,,,,,,,,,, + ,,,,,,,,,, ,,,,,,,,,, + ,,,,,,,,,, ,,,,,,,,,, + ,,,,,,,,,, ,,,,,,,,,, + ,,,,,,,,) ; s010. s000 : ABS_BEAMFREE ( handle ) ; s020. - s000 : ABS_BEAMPOINTTO (,,,,) ; s000. - s000 : ABS_WGSETTINGS (,) ; s030. + s000 : ABS_BEAMPOINTTO (,,,,) ; s030. + s000 : ABS_WGSETTINGS (,) ; s040. s000 : ABS_WGENABLE ; s000. s000 : ABS_WGDISABLE ; s000. + s000 : R_SIG( stop ) ; finish. - s010 : ABS_BEAMALLOC_ACK ( 0x00000001, 0x00000000 ) ; s000. + s010 : S_SIG( bs_alloc_ack ) + ABS_BEAMALLOC_ACK ( 0x00000001, 0x00000000 ) ; s000. s020 : ABS_BEAMFREE_ACK ( handle, 0x00000000 ) ; s000. - s030 : ABS_WGSETTINGS_ACK ( 0x00000000 ) ; s000. - -// s90 : R_SIG (time_is_over) ; s100. -// s90 : TIMER (0x10) ; s110. // not received the 'sent' in time so quit - - s900 : S_SIG (ready ) ; OK. - s910 : TERMINATE. - OK : TIMER(10) ; OK. -} + s030 : S_SIG( bs_pointto_ack ) ; s000. -WaitUntilTestEnd (SM1_ready, SM2_ready) = -{ - s01 : R_SIG (SM1_ready) ; s02. - s02 : R_SIG (SM2_ready) ; s03. - s03 : TERMINATE. + s040 : ABS_WGSETTINGS_ACK ( 0x00000000 ) ; s000. + + finish : TERMINATE ; finish. } -HALF_HOUR_TIMER (half_hour_over_1, half_hour_over_2) = +WaitUntilTestEnd (SM1_ready) = { - s000 : TIMER (0x057E) ; s010. - s010 : S_SIG (half_hour_over_1) ; s020. - s020 : S_SIG (half_hour_over_2) ; s000. + s010 : R_SIG (SM1_ready) ; finish. + finish : TERMINATE ; finish. } [testscript] -VAR SM1_done, SM2_done, TMO_1, TMO_2. +VAR SM1_done, SM2_stop, bs_alloc_ack, bs_pointto_ack. -COM1 : Statemachine_MACScheduler (SM1_done, TMO_1) - HALF_HOUR_TIMER (TMO_1, TMO_2) - WaitUntilTestEnd (SM1_done, SM2_done). +COM1 : Statemachine_MACScheduler (SM1_done, SM2_stop, bs_alloc_ack, bs_pointto_ack) + WaitUntilTestEnd (SM1_done). -COM2 : Statemachine_BeamServer (SM2_done, TMO_2). +COM2 : Statemachine_BeamServer (SM2_stop, bs_alloc_ack, bs_pointto_ack). diff --git a/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.prot b/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.prot index 80739bef515dfda23b0444c364b67de344979167..edcb07092cb1320503d0dd2b8af5ee9c4ccc8bb8 100644 --- a/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.prot +++ b/MAC/APL/_GSO/MACScheduler/test/CCU_increment1.prot @@ -110,6 +110,21 @@ t_Long = { 4 } t_uLong = { 4 } t_String50 = -{ 50, ASCII_0 } // (-) indicates little endian; strings are padded with \0 +// +// NOTE: String workaround. The current version of the TestHarness for Lofar +// has no native support for strings as used by Lofar. Lofar expects a string +// to be prefixed by a 32 bit number that defines the length of the string that +// follows. The TestHarness only supports 0-terminated strings and fixed size strings +// with length prefixes. +// This protocol uses 0-terminated strings with a maximum length of 50 characters +// It is possible to send less characters, but the total string length remains 50 +// characters and is padded with \0 characters. +// The string is prepended with a constant indicating the length of the string +// For example: +// 0x32000000, // string length, big endian +// VIrootID : t_String50 +// + // SAS enums t_SAS_Result = { 4, 0x00000000, 0x00000004, ENUM, 0x00000000 : "NO_ERROR", @@ -163,8 +178,8 @@ SAS_SCHEDULE = { 0x01, // signal Id 0x4D, // Direction and protocol - 0x36000000, // message payload length. Depends on string length - 0x32000000, // string length + 0x36000000, // message payload length. Depends on string length, big endian + 0x32000000, // string length, big endian VIrootID : t_String50 } @@ -172,8 +187,8 @@ SAS_UPDATESCHEDULE = { 0x02, // signal Id 0x4D, // Direction and protocol - 0x36000000, // message payload length. Depends on string length - 0x32000000, // string length + 0x36000000, // message payload length. Depends on string length, big endian + 0x32000000, // string length, big endian VIrootID : t_String50 } @@ -181,8 +196,8 @@ SAS_CANCELSCHEDULE = { 0x03, // signal Id 0x4D, // Direction and protocol - 0x36000000, // message payload length. Depends on string length - 0x32000000, // string length + 0x36000000, // message payload length. Depends on string length, big endian + 0x32000000, // string length, big endian VIrootID : t_String50 } @@ -191,7 +206,7 @@ ABS_BEAMALLOC_ACK = { 0x02, // signal Id 0x94, // Direction and protocol - 0x0800000, // message payload length + 0x0800000, // message payload length, big endian handle : t_Int, status : t_ABS_Result } @@ -200,7 +215,7 @@ ABS_BEAMFREE_ACK = { 0x04, // signal Id 0x94, // Direction and protocol - 0x0800000, // message payload length + 0x0800000, // message payload length, big endian handle : t_Int, status : t_ABS_Result } @@ -209,7 +224,7 @@ ABS_WGSETTINGS_ACK = { 0x07, // signal Id 0x94, // Direction and protocol - 0x04000000, // message payload length + 0x04000000, // message payload length, big endian status : t_ABS_Result } @@ -221,7 +236,7 @@ SAS_RESPONSE = { 0x04, // signal Id 0x8D, // Direction and protocol - 0x04000000, // message payload length + 0x04000000, // message payload length, big endian result : t_SAS_Result } @@ -229,8 +244,8 @@ SAS_REPLACEMENT_REQUEST = { 0x05, // signal Id 0x8D, // Direction and protocol - 0x36000000, // message payload length. Depends on string length - 0x32000000, // string length + 0x36000000, // message payload length. Depends on string length, big endian + 0x32000000, // string length, big endian nodeID : t_String50 } @@ -239,144 +254,49 @@ ABS_BEAMALLOC = { 0x01, // signal Id 0x54, // Direction and protocol - 0x08040000, // message payload length + 0x08020000, // message payload length, big endian spectral_window : t_Int, n_subbands : t_Int, - subband1 : t_Int, // the subbands array has a length of 128 integers - subband2 : t_Int, - subband3 : t_Int, - subband4 : t_Int, - subband5 : t_Int, - subband6 : t_Int, - subband7 : t_Int, - subband8 : t_Int, - subband9 : t_Int, - subband10 : t_Int, - subband11 : t_Int, - subband12 : t_Int, - subband13 : t_Int, - subband14 : t_Int, - subband15 : t_Int, - subband16 : t_Int, - subband17 : t_Int, - subband18 : t_Int, - subband19 : t_Int, - subband20 : t_Int, - subband21 : t_Int, - subband22 : t_Int, - subband23 : t_Int, - subband24 : t_Int, - subband25 : t_Int, - subband26 : t_Int, - subband27 : t_Int, - subband28 : t_Int, - subband29 : t_Int, - subband30 : t_Int, - subband31 : t_Int, - subband32 : t_Int, - subband33 : t_Int, - subband34 : t_Int, - subband35 : t_Int, - subband36 : t_Int, - subband37 : t_Int, - subband38 : t_Int, - subband39 : t_Int, - subband40 : t_Int, - subband41 : t_Int, - subband42 : t_Int, - subband43 : t_Int, - subband44 : t_Int, - subband45 : t_Int, - subband46 : t_Int, - subband47 : t_Int, - subband48 : t_Int, - subband49 : t_Int, - subband50 : t_Int, - subband51 : t_Int, - subband52 : t_Int, - subband53 : t_Int, - subband54 : t_Int, - subband55 : t_Int, - subband56 : t_Int, - subband57 : t_Int, - subband58 : t_Int, - subband59 : t_Int, - subband60 : t_Int, - subband61 : t_Int, - subband62 : t_Int, - subband63 : t_Int, - subband64 : t_Int, - subband65 : t_Int, - subband66 : t_Int, - subband67 : t_Int, - subband68 : t_Int, - subband69 : t_Int, - subband70 : t_Int, - subband71 : t_Int, - subband72 : t_Int, - subband73 : t_Int, - subband74 : t_Int, - subband75 : t_Int, - subband76 : t_Int, - subband77 : t_Int, - subband78 : t_Int, - subband79 : t_Int, - subband80 : t_Int, - subband81 : t_Int, - subband82 : t_Int, - subband83 : t_Int, - subband84 : t_Int, - subband85 : t_Int, - subband86 : t_Int, - subband87 : t_Int, - subband88 : t_Int, - subband89 : t_Int, - subband90 : t_Int, - subband91 : t_Int, - subband92 : t_Int, - subband93 : t_Int, - subband94 : t_Int, - subband95 : t_Int, - subband96 : t_Int, - subband97 : t_Int, - subband98 : t_Int, - subband99 : t_Int, - subband100 : t_Int, - subband101 : t_Int, - subband102 : t_Int, - subband103 : t_Int, - subband104 : t_Int, - subband105 : t_Int, - subband106 : t_Int, - subband107 : t_Int, - subband108 : t_Int, - subband109 : t_Int, - subband110 : t_Int, - subband111 : t_Int, - subband112 : t_Int, - subband113 : t_Int, - subband114 : t_Int, - subband115 : t_Int, - subband116 : t_Int, - subband117 : t_Int, - subband118 : t_Int, - subband119 : t_Int, - subband120 : t_Int, - subband121 : t_Int, - subband122 : t_Int, - subband123 : t_Int, - subband124 : t_Int, - subband125 : t_Int, - subband126 : t_Int, - subband127 : t_Int, - subband128 : t_Int + // the subbands array has a length of 128 integers + subband1 : t_Int, subband2 : t_Int, subband3 : t_Int, subband4 : t_Int, + subband5 : t_Int, subband6 : t_Int, subband7 : t_Int, subband8 : t_Int, + subband9 : t_Int, subband10 : t_Int, subband11 : t_Int, subband12 : t_Int, + subband13 : t_Int, subband14 : t_Int, subband15 : t_Int, subband16 : t_Int, + subband17 : t_Int, subband18 : t_Int, subband19 : t_Int, subband20 : t_Int, + subband21 : t_Int, subband22 : t_Int, subband23 : t_Int, subband24 : t_Int, + subband25 : t_Int, subband26 : t_Int, subband27 : t_Int, subband28 : t_Int, + subband29 : t_Int, subband30 : t_Int, subband31 : t_Int, subband32 : t_Int, + subband33 : t_Int, subband34 : t_Int, subband35 : t_Int, subband36 : t_Int, + subband37 : t_Int, subband38 : t_Int, subband39 : t_Int, subband40 : t_Int, + subband41 : t_Int, subband42 : t_Int, subband43 : t_Int, subband44 : t_Int, + subband45 : t_Int, subband46 : t_Int, subband47 : t_Int, subband48 : t_Int, + subband49 : t_Int, subband50 : t_Int, subband51 : t_Int, subband52 : t_Int, + subband53 : t_Int, subband54 : t_Int, subband55 : t_Int, subband56 : t_Int, + subband57 : t_Int, subband58 : t_Int, subband59 : t_Int, subband60 : t_Int, + subband61 : t_Int, subband62 : t_Int, subband63 : t_Int, subband64 : t_Int, + subband65 : t_Int, subband66 : t_Int, subband67 : t_Int, subband68 : t_Int, + subband69 : t_Int, subband70 : t_Int, subband71 : t_Int, subband72 : t_Int, + subband73 : t_Int, subband74 : t_Int, subband75 : t_Int, subband76 : t_Int, + subband77 : t_Int, subband78 : t_Int, subband79 : t_Int, subband80 : t_Int, + subband81 : t_Int, subband82 : t_Int, subband83 : t_Int, subband84 : t_Int, + subband85 : t_Int, subband86 : t_Int, subband87 : t_Int, subband88 : t_Int, + subband89 : t_Int, subband90 : t_Int, subband91 : t_Int, subband92 : t_Int, + subband93 : t_Int, subband94 : t_Int, subband95 : t_Int, subband96 : t_Int, + subband97 : t_Int, subband98 : t_Int, subband99 : t_Int, subband100 : t_Int, + subband101 : t_Int, subband102 : t_Int, subband103 : t_Int, subband104 : t_Int, + subband105 : t_Int, subband106 : t_Int, subband107 : t_Int, subband108 : t_Int, + subband109 : t_Int, subband110 : t_Int, subband111 : t_Int, subband112 : t_Int, + subband113 : t_Int, subband114 : t_Int, subband115 : t_Int, subband116 : t_Int, + subband117 : t_Int, subband118 : t_Int, subband119 : t_Int, subband120 : t_Int, + subband121 : t_Int, subband122 : t_Int, subband123 : t_Int, subband124 : t_Int, + subband125 : t_Int, subband126 : t_Int, subband127 : t_Int, subband128 : t_Int } ABS_BEAMFREE = { 0x03, // signal Id 0x54, // Direction and protocol - 0x04000000, // message payload length + 0x04000000, // message payload length, big endian handle : t_Int } @@ -384,7 +304,7 @@ ABS_BEAMPOINTTO = { 0x05, // signal Id 0x54, // Direction and protocol - 0x1C000000, // message payload length + 0x1C000000, // message payload length, big endian handle : t_Int, time : t_Int, type : t_Int, @@ -396,7 +316,7 @@ ABS_WGSETTINGS = { 0x06, // signal Id 0x54, // Direction and protocol - 0x0C000000, // message payload length + 0x0C000000, // message payload length, big endian frequency : t_Double, amplitude : t_uShort } @@ -405,12 +325,12 @@ ABS_WGENABLE = { 0x08, // signal Id 0x54, // Direction and protocol - 0x00000000 // message payload length + 0x00000000 // message payload length, big endian } ABS_WGDISABLE = { 0x09, // signal Id 0x54, // Direction and protocol - 0x00000000 // message payload length + 0x00000000 // message payload length, big endian } diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc index 1e25e09889b7a29da0f352ef7370ee3205b6e30a..2ef1037bac679faf3853dca5bfbc2ae7751318e2 100644 --- a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc +++ b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.cc @@ -42,7 +42,9 @@ INIT_TRACER_CONTEXT(VirtualInstrument,LOFARLOGGER_PACKAGE); VirtualInstrument::VirtualInstrument(const string& taskName, const string& parameterFile) : LogicalDevice(taskName,parameterFile), - m_vtSchedulerPropertySets() + m_vtSchedulerPropertySets(), + m_disconnectedVTSchedulerPropertySets(), + m_retryPropsetLoadTimerId(0) { LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,getName().c_str()); @@ -77,6 +79,7 @@ VirtualInstrument::VirtualInstrument(const string& taskName, const string& param { THROW(APLCommon::ParameterNotFoundException,e.message()); } + m_retryPropsetLoadTimerId = m_serverPort.setTimer(10L); } @@ -117,41 +120,23 @@ void VirtualInstrument::concrete_handlePropertySetAnswer(::GCFEvent& answer) { if(strstr(pPropAnswer->pScope, it->second->getScope().c_str()) != 0) { - try - { - stringstream schedule; - schedule << "SCHEDULE "; - // SCHEDULE <sch.nr>,VT,<vt_name>,<bf_name>,<srg_name>,<starttime>,<stoptime>, - // <frequency>,<subbands>,<directiontype>,<angle1>,<angle2> - schedule << "1,"; - schedule << "VT,"; - schedule << it->first << ","; - - string childs = m_parameterSet.getString(it->first + string(".") + string("childs")); - vector<string> childsVector; - APLUtilities::string2Vector(childs,childsVector); - - schedule << childsVector[0] << ","; - schedule << childsVector[1] << ","; - time_t startTime = _decodeTimeParameter(m_parameterSet.getString(it->first + string(".") + string("startTime"))); - schedule << startTime << ","; - time_t stopTime = _decodeTimeParameter(m_parameterSet.getString(it->first + string(".") + string("stopTime"))); - schedule << stopTime << ","; - - schedule << m_parameterSet.getString(it->first + string(".") + string("frequency")) << ","; - schedule << m_parameterSet.getString(it->first + string(".") + string("subbands")) << ","; - schedule << m_parameterSet.getString(it->first + string(".") + string("directionType")) << ","; - schedule << m_parameterSet.getString(it->first + string(".") + string("angle1")) << ","; - schedule << m_parameterSet.getString(it->first + string(".") + string("angle2")) << ","; - - GCFPVString pvSchedule(schedule.str()); - it->second->setValue("command",pvSchedule); - scheduleSent = true; - } - catch(Exception& e) - { - LOG_FATAL(e.message().c_str()); - } + scheduleSent = _writeScheduleCommand(it->first,it->second); + } + ++it; + } + } + else + { + LOG_WARN(formatString("failed to load propertyset %s",pPropAnswer->pScope)); + + bool propsetFound=false; + TString2PropsetMap::iterator it=m_vtSchedulerPropertySets.begin(); + while(!propsetFound && it!=m_vtSchedulerPropertySets.end()) + { + if(strstr(pPropAnswer->pScope, it->second->getScope().c_str()) != 0) + { + m_disconnectedVTSchedulerPropertySets[it->first] = it->second; + propsetFound=true; } ++it; } @@ -230,7 +215,7 @@ void VirtualInstrument::concrete_handlePropertySetAnswer(::GCFEvent& answer) { LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,formatString("%s - event=%s",getName().c_str(),evtstr(event)).c_str()); ::GCFEvent::TResult status = GCFEvent::NOT_HANDLED; - newState=LOGICALDEVICE_STATE_NOSTATE; + newState=LOGICALDEVICE_STATE_CLAIMED; return status; } @@ -239,16 +224,15 @@ void VirtualInstrument::concrete_handlePropertySetAnswer(::GCFEvent& answer) { LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,formatString("%s - event=%s",getName().c_str(),evtstr(event)).c_str()); ::GCFEvent::TResult status = GCFEvent::NOT_HANDLED; - newState=LOGICALDEVICE_STATE_NOSTATE; + newState=LOGICALDEVICE_STATE_SUSPENDED; return status; } -::GCFEvent::TResult VirtualInstrument::concrete_active_state(::GCFEvent& event, ::GCFPortInterface& /*p*/, TLogicalDeviceState& newState) +::GCFEvent::TResult VirtualInstrument::concrete_active_state(::GCFEvent& event, ::GCFPortInterface& /*p*/) { LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,formatString("%s - event=%s",getName().c_str(),evtstr(event)).c_str()); ::GCFEvent::TResult status = GCFEvent::NOT_HANDLED; - newState=LOGICALDEVICE_STATE_NOSTATE; return status; } @@ -257,7 +241,8 @@ void VirtualInstrument::concrete_handlePropertySetAnswer(::GCFEvent& answer) { LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,formatString("%s - event=%s",getName().c_str(),evtstr(event)).c_str()); ::GCFEvent::TResult status = GCFEvent::NOT_HANDLED; - newState=LOGICALDEVICE_STATE_NOSTATE; + + newState=LOGICALDEVICE_STATE_RELEASED; return status; } @@ -286,6 +271,22 @@ void VirtualInstrument::concreteSuspend(::GCFPortInterface& /*port*/) void VirtualInstrument::concreteRelease(::GCFPortInterface& /*port*/) { LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,getName().c_str()); + + // workaround for old style Virtual Telescope: set command property + TString2PropsetMap::iterator it; + for(it=m_vtSchedulerPropertySets.begin();it!=m_vtSchedulerPropertySets.end();++it) + { + try + { + string cancelMessage("CANCEL 1"); + GCFPVString pvCancel(cancelMessage); + it->second->setValue("command",pvCancel); + } + catch(Exception& e) + { + LOG_FATAL(e.message().c_str()); + } + } } void VirtualInstrument::concreteParentDisconnected(::GCFPortInterface& /*port*/) @@ -298,5 +299,67 @@ void VirtualInstrument::concreteChildDisconnected(::GCFPortInterface& /*port*/) LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,getName().c_str()); } +void VirtualInstrument::concreteHandleTimers(::GCFTimerEvent& timerEvent, ::GCFPortInterface& /*port*/) +{ + LOG_TRACE_LIFETIME(TRACE_LEVEL_FLOW,getName().c_str()); + if(timerEvent.id == m_retryPropsetLoadTimerId) + { + // loop through the buffered events and try to send each one. + TString2PropsetMap::iterator it = m_disconnectedVTSchedulerPropertySets.begin(); + while(it != m_disconnectedVTSchedulerPropertySets.end()) + { + _writeScheduleCommand(it->first,it->second); + // remove the event from the map. If the propset cannot be loaded, it will + // be added again later on. + m_disconnectedVTSchedulerPropertySets.erase(it); + it = m_disconnectedVTSchedulerPropertySets.begin(); + } + + // keep on polling + m_retryPropsetLoadTimerId = m_serverPort.setTimer(10L); + } +} + +bool VirtualInstrument::_writeScheduleCommand(const string& name, TGCFExtPropertySetPtr& propset) +{ + bool scheduleSent(false); + try + { + stringstream schedule; + schedule << "SCHEDULE "; + // SCHEDULE <sch.nr>,VT,<vt_name>,<bf_name>,<srg_name>,<starttime>,<stoptime>, + // <frequency>,<subbands>,<directiontype>,<angle1>,<angle2> + schedule << "1,"; + schedule << "VT,"; + schedule << name << ","; + + string childs = m_parameterSet.getString(name + string(".") + string("childs")); + vector<string> childsVector; + APLUtilities::string2Vector(childs,childsVector); + + schedule << childsVector[0] << ","; + schedule << childsVector[1] << ","; + time_t startTime = _decodeTimeParameter(m_parameterSet.getString(name + string(".") + string("startTime"))); + schedule << startTime << ","; + time_t stopTime = _decodeTimeParameter(m_parameterSet.getString(name + string(".") + string("stopTime"))); + schedule << stopTime << ","; + + schedule << m_parameterSet.getString(name + string(".") + string("frequency")) << ","; + schedule << m_parameterSet.getString(name + string(".") + string("subbands")) << ","; + schedule << m_parameterSet.getString(name + string(".") + string("directionType")) << ","; + schedule << m_parameterSet.getString(name + string(".") + string("angle1")) << ","; + schedule << m_parameterSet.getString(name + string(".") + string("angle2")) << ","; + + GCFPVString pvSchedule(schedule.str()); + propset->setValue("command",pvSchedule); + scheduleSent = true; + } + catch(Exception& e) + { + LOG_FATAL(e.message().c_str()); + } + return scheduleSent; +} + }; // namespace VIC }; // namespace LOFAR diff --git a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.h b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.h index d3d53a2acce16daeef8dc871994d9f2073e6b7dc..5972c88aafcec61b14ffc1ffdde1b29074550c80 100644 --- a/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.h +++ b/MAC/APL/_VIC/VirtualInstrument/src/VirtualInstrument.h @@ -78,7 +78,7 @@ namespace AVI /** * active state additional behaviour must be implemented in the derived classes. */ - virtual ::GCFEvent::TResult concrete_active_state(::GCFEvent& e, ::GCFPortInterface& p, TLogicalDeviceState& newState); + virtual ::GCFEvent::TResult concrete_active_state(::GCFEvent& e, ::GCFPortInterface& p); /** * Releasing state additional behaviour must be implemented in the derived classes. */ @@ -112,6 +112,7 @@ namespace AVI * Implementation of the Disconnected handler is done in the derived classes. */ virtual void concreteChildDisconnected(::GCFPortInterface& port); + virtual void concreteHandleTimers(::GCFTimerEvent& timerEvent, ::GCFPortInterface& port); protected: @@ -119,7 +120,12 @@ namespace AVI typedef boost::shared_ptr<GCFExtPropertySet> TGCFExtPropertySetPtr; typedef std::map<std::string,TGCFExtPropertySetPtr> TString2PropsetMap; - TString2PropsetMap m_vtSchedulerPropertySets; + bool _writeScheduleCommand(const string& name, TGCFExtPropertySetPtr& propset); + + TString2PropsetMap m_vtSchedulerPropertySets; + TString2PropsetMap m_disconnectedVTSchedulerPropertySets; + unsigned long m_retryPropsetLoadTimerId; + ALLOC_TRACER_CONTEXT };