From 42d2af80fe295ade26f7fe423b2f45b916b8c221 Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Thu, 12 Jun 2008 12:32:52 +0000
Subject: [PATCH] Bug 1196: Added a command rspctl --realdelays to return the
 delay-values from the tiles. Value 255 is returned when an element is broken.
 Since I inserted a command in the RSPprotocol I increased the
 RSP_versionnumber to 3.1 in MACServiceInfo.h.

---
 MAC/APL/PIC/RSPDriver/src/Cache.cc            |   13 +
 MAC/APL/PIC/RSPDriver/src/Cache.h             |    2 +
 MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc |  133 +-
 MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc    |  115 +-
 MAC/APL/PIC/RSPDriver/src/Makefile.am         |    2 +
 MAC/APL/PIC/RSPDriver/src/RSPDriver.cc        |   36 +-
 MAC/APL/PIC/RSPDriver/src/RSPDriver.h         |    1 +
 MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc       |  110 ++
 MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h        |   78 +
 MAC/APL/PIC/RSPDriver/src/rspctl.cc           | 1673 +++++++++--------
 .../PIC/RSP_Protocol/src/RSP_Protocol.prot    |   39 +
 MAC/MACIO/include/MACIO/MACServiceInfo.h      |    2 +-
 12 files changed, 1272 insertions(+), 932 deletions(-)
 create mode 100644 MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h

diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.cc b/MAC/APL/PIC/RSPDriver/src/Cache.cc
index 54926b7d846..c42c82077c2 100644
--- a/MAC/APL/PIC/RSPDriver/src/Cache.cc
+++ b/MAC/APL/PIC/RSPDriver/src/Cache.cc
@@ -62,6 +62,8 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache)
   LOG_DEBUG_STR("m_beamletweights().size()     =" << m_beamletweights().size()     * sizeof(complex<int16>));
   LOG_DEBUG_STR("m_subbandselection().size()   =" << m_subbandselection().size()   * sizeof(uint16));
   LOG_DEBUG_STR("m_rcusettings().size()        =" << m_rcusettings().size()        * sizeof(uint8));
+  LOG_DEBUG_STR("m_hbasettings().size()        =" << m_hbasettings().size()        * sizeof(uint8));
+  LOG_DEBUG_STR("m_hbareadings().size()        =" << m_hbareadings().size()        * sizeof(uint8));
   LOG_DEBUG_STR("m_rsusettings().size()        =" << m_rsusettings().size()        * sizeof(uint8));
   LOG_DEBUG_STR("m_wgsettings().size()         =" << m_wgsettings().size()         * sizeof(WGSettings::WGRegisterType));
   LOG_DEBUG_STR("m_subbandstats().size()       =" << m_subbandstats().size()       * sizeof(uint16));
@@ -78,6 +80,8 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache)
 	         m_beamletweights().size()    	       
 	       + m_subbandselection().size()  
 	       + m_rcusettings().size()       
+	       + m_hbasettings().size()       
+	       + m_hbareadings().size()       
 	       + m_rsusettings().size()       
 	       + m_wgsettings().size()        
 	       + m_subbandstats().size()      
@@ -96,6 +100,8 @@ CacheBuffer::~CacheBuffer()
   m_beamletweights().free();
   m_subbandselection().free();
   m_rcusettings().free();
+  m_hbasettings().free();
+  m_hbareadings().free();
   m_rsusettings().free();
   m_wgsettings().free();
   m_wgsettings.waveforms().free();
@@ -154,6 +160,8 @@ void CacheBuffer::reset(void)
   // initialize HBA settings
   m_hbasettings().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_HBA_DELAYS);
   m_hbasettings() = 0; // initialize to 0
+  m_hbareadings().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_HBA_DELAYS);
+  m_hbareadings() = 0; // initialize to 0
 
   // RSU settings
   m_rsusettings().resize(StationSettings::instance()->nrRspBoards());
@@ -245,6 +253,11 @@ HBASettings& CacheBuffer::getHBASettings()
   return m_hbasettings;
 }
 
+HBASettings& CacheBuffer::getHBAReadings()
+{
+  return m_hbareadings;
+}
+
 RSUSettings& CacheBuffer::getRSUSettings()
 {
   return m_rsusettings;
diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.h b/MAC/APL/PIC/RSPDriver/src/Cache.h
index d9f4282332d..aca9584693a 100644
--- a/MAC/APL/PIC/RSPDriver/src/Cache.h
+++ b/MAC/APL/PIC/RSPDriver/src/Cache.h
@@ -60,6 +60,7 @@ namespace LOFAR {
       RSP_Protocol::SubbandSelection&  getSubbandSelection();
       RSP_Protocol::RCUSettings&       getRCUSettings();
       RSP_Protocol::HBASettings&       getHBASettings();
+      RSP_Protocol::HBASettings&       getHBAReadings();
       RSP_Protocol::RSUSettings&       getRSUSettings();
       RSP_Protocol::WGSettings&        getWGSettings();
       RSP_Protocol::SystemStatus&      getSystemStatus();
@@ -103,6 +104,7 @@ namespace LOFAR {
       RSP_Protocol::SubbandSelection m_subbandselection;
       RSP_Protocol::RCUSettings      m_rcusettings;
       RSP_Protocol::HBASettings      m_hbasettings;
+      RSP_Protocol::HBASettings      m_hbareadings;
       RSP_Protocol::RSUSettings      m_rsusettings;
       RSP_Protocol::WGSettings       m_wgsettings;
       RSP_Protocol::Statistics       m_subbandstats;
diff --git a/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc
index 9ffe9ae4e19..90967c677df 100644
--- a/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc
+++ b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc
@@ -297,87 +297,83 @@ HBAProtocolWrite::~HBAProtocolWrite()
 
 void HBAProtocolWrite::sendrequest()
 {
-  uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES);
+	uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES);
 
-  // only update if rcuprotocol is not being updated and one of hbaprotocol needs updating
-  if (RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL)
-      || RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL + 1))
-  {
-    setContinue(true);
-    return;
-  }
+	// only update if rcuprotocol is not being updated and one of hbaprotocol needs updating
+	if (RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL)
+	 || RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL + 1)) {
+		setContinue(true);
+		return;
+	}
    
-  if (RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL)
-      && RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1))
-  {
-    Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL);
-    Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL + 1);
-    setContinue(true);
-    return;
-  }
+	if (RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL)
+	 && RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) {
+		Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL);
+		Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL + 1);
+		setContinue(true);
+		return;
+	}
 
-  // delays for at least on HBA need to be written, and the RCUProtocol register is not in use by RCUProtocolWrite
+	// delays for at least on HBA need to be written, and the RCUProtocol register is not in use by RCUProtocolWrite
 
 	LOG_INFO_STR("HBAsendrequest: " << getCurrentIndex());
-  switch (getCurrentIndex() % N_WRITES) {
-    
-  case 0:
-    {
+	switch (getCurrentIndex() % N_WRITES) {
+	case 0: {
 #ifdef HBA_WRITE_DELAYS
-      if (PROTOCOL_DELAY_OFFSET > 0) {
-	Array<uint8, 2> delays(i2c_protocol + PROTOCOL_DELAY_OFFSET,
-			       shape(MEPHeader::N_HBA_DELAYS, 2),
-			       neverDeleteData);
+		if (PROTOCOL_DELAY_OFFSET > 0) {
+			Array<uint8, 2> delays(i2c_protocol + PROTOCOL_DELAY_OFFSET,
+									shape(MEPHeader::N_HBA_DELAYS, 2),
+									neverDeleteData);
 
-	delays(Range::all(), 0) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL, Range::all());
-	delays(Range::all(), 1) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL + 1, Range::all());
+			delays(Range::all(), 0) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL, Range::all());
+			delays(Range::all(), 1) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL + 1, Range::all());
 	
-	// copy set delays to i2c_result which is the expected result
-	uint8* cur = i2c_result + RESULT_DELAY_OFFSET;
-	for (int elem = 0; elem < MEPHeader::N_HBA_DELAYS; elem++){
-	  *(cur+0) = delays(elem, 0); // X
-	  *(cur+1) = delays(elem, 1); // Y
-	  cur += RESULT_DELAY_STRIDE;
+			// copy set delays to i2c_result which is the expected result
+			uint8* cur = i2c_result + RESULT_DELAY_OFFSET;
+			for (int elem = 0; elem < MEPHeader::N_HBA_DELAYS; elem++){
+				*(cur+0) = delays(elem, 0); // X
+				*(cur+1) = delays(elem, 1); // Y
+				cur += RESULT_DELAY_STRIDE;
+			}
+		}
+#else
+		i2c_protocol[PROTOCOL_LED_OFFSET] = (m_on_off ? 0xf : 0x0);
+		i2c_result[RESULT_LED_OFFSET] = i2c_protocol[PROTOCOL_LED_OFFSET];
+		LOG_INFO(formatString("Switch LED (HBA_blp=%d) %s", global_blp, m_on_off ? "on" : "off"));
+#endif
+		// create the event
+		EPARcuProtocolEvent rcuprotocol;
+		rcuprotocol.hdr.set(MEPHeader::RCU_PROTOCOLY_HDR, 1 << (getCurrentIndex() / N_WRITES), MEPHeader::WRITE, sizeof(i2c_protocol));
+		rcuprotocol.protocol.setBuffer(i2c_protocol, sizeof(i2c_protocol));
+
+		string tmpbuf;
+		hexdump (tmpbuf, i2c_protocol, sizeof(i2c_protocol));
+		LOG_INFO_STR("HBA WRITE: " << tmpbuf);
+  
+		m_hdr = rcuprotocol.hdr; // remember header to match with ack
+		getBoardPort().send(rcuprotocol);
 	}
-      }
+	break;
 
-#else
+	case 1: {
+		EPAWriteEvent rcuresultwrite;
 
-      i2c_protocol[PROTOCOL_LED_OFFSET] = (m_on_off ? 0xf : 0x0);
-      i2c_result[RESULT_LED_OFFSET] = i2c_protocol[PROTOCOL_LED_OFFSET];
-      LOG_INFO(formatString("Switch LED (HBA_blp=%d) %s", global_blp, m_on_off ? "on" : "off"));
+		// set the result register to 0xBB's
+		rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / N_WRITES),
+		MEPHeader::RCU, MEPHeader::RCU_RESULTY, sizeof(i2c_result), 0);
+		uint8 clear[RESULT_SIZE];
+		memset(clear, 0xBB, RESULT_SIZE); // clear result
+		rcuresultwrite.payload.setBuffer(clear, RESULT_SIZE);
 
-#endif
+		string tmpbuf;
+		hexdump (tmpbuf, clear, sizeof(clear));
+		LOG_INFO_STR("HBA RESULT WRITE: " << tmpbuf);
 
-      // create the event
-      EPARcuProtocolEvent rcuprotocol;
-      rcuprotocol.hdr.set(MEPHeader::RCU_PROTOCOLY_HDR, 1 << (getCurrentIndex() / N_WRITES), MEPHeader::WRITE, sizeof(i2c_protocol));
-      rcuprotocol.protocol.setBuffer(i2c_protocol, sizeof(i2c_protocol));
-	  string tmpbuf;
-	  hexdump (tmpbuf, i2c_protocol, sizeof(i2c_protocol));
-	  LOG_INFO_STR("HBA WRITE: " << tmpbuf);
-  
-      m_hdr = rcuprotocol.hdr; // remember header to match with ack
-      getBoardPort().send(rcuprotocol);
-    }
-    break;
-
-  case 1:
-    {
-      EPAWriteEvent rcuresultwrite;
-
-      // set the result register to 0xBB's
-      rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / N_WRITES),
-			     MEPHeader::RCU, MEPHeader::RCU_RESULTY, sizeof(i2c_result), 0);
-      uint8 clear[RESULT_SIZE];
-      memset(clear, 0xBB, RESULT_SIZE); // clear result
-      rcuresultwrite.payload.setBuffer(clear, RESULT_SIZE);
-
-      m_hdr = rcuresultwrite.hdr; // remember header to match with ack
-      getBoardPort().send(rcuresultwrite);
-    }
-    break;
-  }
+		m_hdr = rcuresultwrite.hdr; // remember header to match with ack
+		getBoardPort().send(rcuresultwrite);
+	}
+	break;
+	}
 }
 
 void HBAProtocolWrite::sendrequest_status()
@@ -397,6 +393,7 @@ GCFEvent::TResult HBAProtocolWrite::handleack(GCFEvent& event, GCFPortInterface&
 
   uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES);
 
+LOG_INFO_STR("hba[" << (int)(global_blp) << "]: handleAck");
   if (!ack.hdr.isValidAck(m_hdr))
   {
     LOG_ERROR("HBAProtocolWrite::handleack: invalid ack");
diff --git a/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc
index 02864ebafe5..ce3118531d2 100644
--- a/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc
+++ b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc
@@ -22,6 +22,7 @@
 
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
+#include <Common/hexdump.h>
 #include <APL/RSP_Protocol/EPA_Protocol.ph>
 
 #include <APL/RTCCommon/PSAccess.h>
@@ -52,58 +53,82 @@ HBAResultRead::~HBAResultRead()
 
 void HBAResultRead::sendrequest()
 {
-  uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex();
-
-  // skip update if the RCU settings have not been applied yet
-  if (RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL)
-      && RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) {
-    setContinue(true);
-    return;
-  }
-
-  // set appropriate header
-  EPAReadEvent rcuresult;
-  rcuresult.hdr.set(MEPHeader::RCU_RESULTY_HDR, 1 << getCurrentIndex(),
-		    MEPHeader::READ, sizeof(HBAProtocolWrite::i2c_result));
-  
-  m_hdr = rcuresult.hdr; // remember header to match with ack
-  getBoardPort().send(rcuresult);
+	uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex();
+	//LOG_DEBUG_STR("HBA request result for " << (int) global_blp);
+
+	// skip update if the RCU settings have not been applied yet
+	if (RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL) &&
+		RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) {
+		setContinue(true);
+		return;
+	}
+
+	// set appropriate header
+	EPAReadEvent rcuresult;
+	rcuresult.hdr.set(MEPHeader::RCU_RESULTY_HDR, 1 << getCurrentIndex(),
+					  MEPHeader::READ, sizeof(HBAProtocolWrite::i2c_result));
+
+	m_hdr = rcuresult.hdr; // remember header to match with ack
+	getBoardPort().send(rcuresult);
 }
 
 void HBAResultRead::sendrequest_status()
 {
-  // intentionally left empty
+	// intentionally left empty
 }
 
 GCFEvent::TResult HBAResultRead::handleack(GCFEvent& event, GCFPortInterface& /*port*/)
 {
-  if (EPA_RCU_RESULT != event.signal)
-  {
-    LOG_WARN("HBAResultRead::handleack:: unexpected ack");
-    return GCFEvent::NOT_HANDLED;
-  }
+	if (EPA_RCU_RESULT != event.signal) {
+		LOG_WARN("HBAResultRead::handleack:: unexpected ack");
+		return GCFEvent::NOT_HANDLED;
+	}
   
-  EPARcuResultEvent ack(event);
-
-  uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex();
-
-  if (!ack.hdr.isValidAck(m_hdr))
-  {
-    LOG_ERROR("HBAResultRead::handleack: invalid ack");
-    Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL);
-    Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1);
-    return GCFEvent::HANDLED;
-  }
-
-  // compare result with expected result
-  if (0 == memcmp(HBAProtocolWrite::i2c_result, ack.result, sizeof(HBAProtocolWrite::i2c_result))) {
-    Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL);
-    Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL + 1);
-  } else {
-    LOG_WARN("HBAResultRead::handleack: unexpected I2C result response");
-    Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL);
-    Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1);
-  }
-
-  return GCFEvent::HANDLED;
+	EPARcuResultEvent ack(event);
+	uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex();
+
+#if 0
+	string received, expected;
+	hexdump (received, (char*)(&(ack.result)), HBAProtocolWrite::RESULT_SIZE);
+	hexdump (expected, HBAProtocolWrite::i2c_result, HBAProtocolWrite::RESULT_SIZE);
+	LOG_INFO_STR("ack for hba[" << (int)(global_blp) << "]=" << received);
+	LOG_INFO_STR("exp for hba[" << (int)(global_blp) << "]=" << expected);
+#endif
+
+	// copy read-values to HBAReadings-cache.
+	string	faultyElements;
+	uint8* cur = ack.result + HBAProtocolWrite::RESULT_DELAY_OFFSET;
+	for (int element = 0; element < MEPHeader::N_HBA_DELAYS; element++) {
+		if ((int)(*(cur-2)) != (int)(0x81+element)) {
+			faultyElements.append(formatString("%d,", element));
+			Cache::getInstance().getBack().getHBAReadings()()((global_blp*2),   element) = 255;	// X
+			Cache::getInstance().getBack().getHBAReadings()()((global_blp*2)+1, element) = 255;	// Y
+		}
+		else {
+			Cache::getInstance().getBack().getHBAReadings()()((global_blp*2),   element) = *(cur+0);	// X
+			Cache::getInstance().getBack().getHBAReadings()()((global_blp*2)+1, element) = *(cur+1);	// Y
+		}
+		cur += HBAProtocolWrite::RESULT_DELAY_STRIDE;
+	}
+
+	// check result
+	if (!ack.hdr.isValidAck(m_hdr)) {
+		LOG_ERROR("HBAResultRead::handleack: invalid ack");
+		Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL);
+		Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1);
+		return GCFEvent::HANDLED;
+	}
+
+	// compare result with expected result
+	if (memcmp(HBAProtocolWrite::i2c_result, ack.result, sizeof(HBAProtocolWrite::i2c_result)) == 0) {
+		Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL);
+		Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL + 1);
+	} else {
+		LOG_WARN_STR("HBAResultRead: unexpected I2C result response for element(s):" << faultyElements << 
+					 " of antenna " << (int)(global_blp));
+		Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL);
+		Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1);
+	}
+
+	return GCFEvent::HANDLED;
 }
diff --git a/MAC/APL/PIC/RSPDriver/src/Makefile.am b/MAC/APL/PIC/RSPDriver/src/Makefile.am
index fccfa1ce24a..d6375e77b6b 100644
--- a/MAC/APL/PIC/RSPDriver/src/Makefile.am
+++ b/MAC/APL/PIC/RSPDriver/src/Makefile.am
@@ -106,6 +106,8 @@ RSPDriverFiles = \
 	SetHBACmd.cc \
 	GetHBACmd.h \
 	GetHBACmd.cc \
+	ReadHBACmd.h \
+	ReadHBACmd.cc \
 	UpdHBACmd.h \
 	UpdHBACmd.cc \
 	SetRSUCmd.h \
diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
index 867278f7ac0..bc7e226d963 100644
--- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
+++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
@@ -60,6 +60,7 @@
 #include "UpdRCUCmd.h"
 #include "SetHBACmd.h"
 #include "GetHBACmd.h"
+#include "ReadHBACmd.h"
 #include "UpdHBACmd.h"
 #include "SetRSUCmd.h"
 #include "SetWGCmd.h"
@@ -1008,6 +1009,10 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
       rsp_gethba(event, port);
       break;
       
+    case RSP_READHBA:
+      rsp_readhba(event, port);
+      break;
+
     case RSP_SUBHBA:
       rsp_subhba(event, port);
       break;
@@ -1728,6 +1733,35 @@ void RSPDriver::rsp_gethba(GCFEvent& event, GCFPortInterface& port)
   }
 }
 
+//
+// rsp_readhba(event,port)
+//
+void RSPDriver::rsp_readhba(GCFEvent& event, GCFPortInterface& port)
+{
+	Ptr<ReadHBACmd> command = new ReadHBACmd(event, port, Command::READ);
+
+	if (!command->validate()) {
+		LOG_ERROR("READHBA: invalid parameter");
+
+		RSPReadhbaackEvent ack;
+		ack.timestamp = Timestamp(0,0);
+		ack.status = FAILURE;
+		ack.settings().resize(1, 1); // create something to pack
+		ack.settings() = 0;
+		port.send(ack);
+		return;
+	}
+
+	// if null timestamp get value from the cache and acknowledge immediately
+	if ( (Timestamp(0,0) == command->getTimestamp()) && (true == command->readFromCache())) {
+		command->setTimestamp(Cache::getInstance().getFront().getTimestamp());
+		command->ack(Cache::getInstance().getFront());
+	}
+	else {
+		(void)m_scheduler.enter(Ptr<Command>(&(*command)));
+	}
+}
+
 //
 // rsp_subhba(event,port)
 //
@@ -2587,7 +2621,7 @@ void RSPDriver::rsp_gettbb(GCFEvent& event, GCFPortInterface& port)
 //
 int main(int argc, char** argv)
 {
-  GCFTask::init(argc, argv);    // initializes log system
+  GCFTask::init(argc, argv, "RSPDriver");    // initializes log system
   
   LOG_INFO(formatString("Starting up %s", argv[0]));
 
diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
index fdd19b3eb9c..934466c8762 100644
--- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
+++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
@@ -124,6 +124,7 @@ namespace LOFAR {
 
       void rsp_sethba  (GCFEvent& event, GCFPortInterface &port);
       void rsp_gethba  (GCFEvent& event, GCFPortInterface &port);
+      void rsp_readhba (GCFEvent& event, GCFPortInterface &port);
       void rsp_subhba  (GCFEvent& event, GCFPortInterface &port);
       void rsp_unsubhba(GCFEvent& event, GCFPortInterface &port);
 
diff --git a/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc
new file mode 100644
index 00000000000..9da0cbbd0be
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc
@@ -0,0 +1,110 @@
+//#  ReadHBACmd.cc: implementation of the ReadHBACmd class
+//#
+//#  Copyright (C) 2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "ReadHBACmd.h"
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace RSP;
+using namespace RSP_Protocol;
+using namespace RTC;
+
+ReadHBACmd::ReadHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+	m_event = new RSPReadhbaEvent(event);
+
+	setOperation(oper);
+	setPeriod(0);
+	setPort(port);
+}
+
+ReadHBACmd::~ReadHBACmd()
+{
+	delete m_event;
+}
+
+void ReadHBACmd::ack(CacheBuffer& cache)
+{
+LOG_INFO("READHBACMD::ack");
+	RSPReadhbaackEvent ack;
+
+	ack.timestamp = getTimestamp();
+	ack.status = SUCCESS;
+
+	ack.settings().resize(m_event->rcumask.count(), MEPHeader::N_HBA_DELAYS);
+
+	int result_rcu = 0;
+	for (int cache_rcu = 0; cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++) {
+		if (m_event->rcumask[cache_rcu]) {
+			if (cache_rcu < StationSettings::instance()->nrRcus()) {
+				ack.settings()(result_rcu, Range::all()) = cache.getHBAReadings()()(cache_rcu, Range::all());
+			}
+			else {
+				LOG_WARN(formatString("invalid RCU index %d, there are only %d RCU's", cache_rcu, 
+				StationSettings::instance()->nrRcus()));
+			}
+
+			result_rcu++;
+		}
+	}
+  
+	getPort()->send(ack);
+}
+
+void ReadHBACmd::apply(CacheBuffer& /*cache*/, bool /*setModFlag*/)
+{
+	/* intentionally left empty */
+}
+
+void ReadHBACmd::complete(CacheBuffer& cache)
+{
+	ack(cache);
+}
+
+const RTC::Timestamp& ReadHBACmd::getTimestamp() const
+{
+	return (m_event->timestamp);
+}
+
+void ReadHBACmd::setTimestamp(const RTC::Timestamp& timestamp)
+{
+	m_event->timestamp = timestamp;
+}
+
+bool ReadHBACmd::validate() const
+{
+	return ((m_event->rcumask.count() <= (unsigned int)StationSettings::instance()->nrRcus()));
+}
+
+bool ReadHBACmd::readFromCache() const
+{
+	return (m_event->cache);
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h
new file mode 100644
index 00000000000..09ee416d079
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h
@@ -0,0 +1,78 @@
+//#  -*- mode: c++ -*-
+//#
+//#  ReadHBACmd.h: Returns the HBA-delays that are readback fro the tiles.
+//#
+//#  Copyright (C) 2008
+//#  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 READHBACMD_H_
+#define READHBACMD_H_
+
+#include "Command.h"
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+
+#include <Common/LofarTypes.h>
+#include <GCF/TM/GCF_Control.h>
+
+namespace LOFAR {
+  namespace RSP {
+
+class ReadHBACmd : public Command
+{
+public:
+	// Constructors for a ReadHBACmd object.
+	ReadHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper);
+
+	// Destructor for ReadHBACmd.
+	virtual ~ReadHBACmd();
+
+	// Acknowledge the command by sending the appropriate
+	// response on m_port.
+	virtual void ack(CacheBuffer& cache);
+
+	// Make necessary changes to the cache for the next synchronization.
+	// Any changes will be sent to the RSP boards.
+	virtual void apply(CacheBuffer& cache, bool setModFlag = true);
+
+	// Complete the command by sending the appropriate response on
+	// the m_answerport;
+	virtual void complete(CacheBuffer& cache);
+
+	// get timestamp of the event
+	virtual const RTC::Timestamp& getTimestamp() const;
+	virtual void setTimestamp(const RTC::Timestamp& timestamp);
+
+	// Validate the event that underlies the command.
+	virtual bool validate() const;
+
+	// Return true if value should be read from cache.
+	bool readFromCache() const;
+
+private:
+	// default construction not allowed.
+	ReadHBACmd();
+
+	RSPReadhbaEvent* m_event;
+};
+
+  };
+};
+     
+#endif /* READHBACMD_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/rspctl.cc b/MAC/APL/PIC/RSPDriver/src/rspctl.cc
index cb614b2e168..5587187075b 100644
--- a/MAC/APL/PIC/RSPDriver/src/rspctl.cc
+++ b/MAC/APL/PIC/RSPDriver/src/rspctl.cc
@@ -67,6 +67,9 @@ double WGCommand::AMPLITUDE_SCALE = (1.0 * ((uint32)(1 << 11)-1) / (uint32)(1 <<
 // local funtions
 static void usage();
 
+// getting real or sent hba values
+static bool	realDelays = false;
+
 // Constants
 #define BITSOFBYTE 8
 
@@ -529,98 +532,133 @@ HBACommand::HBACommand(GCFPortInterface& port) : Command(port)
 
 void HBACommand::send()
 {
-  if (getMode())
-  {
-    // GET
-    RSPGethbaEvent gethba;
-
-    gethba.timestamp = Timestamp(0,0);
-    gethba.rcumask = getRCUMask();
-    gethba.cache = false;
-
-    m_rspport.send(gethba);
-  }
-  else
-  {
-    // SET
-    RSPSethbaEvent sethba;
-    sethba.timestamp = Timestamp(0,0);
-    sethba.rcumask = getRCUMask();
-
-    sethba.settings().resize(sethba.rcumask.count(), MEPHeader::N_HBA_DELAYS);
-
-    if (1 == m_delaylist.size()) {
-      std::list<int>::iterator it = m_delaylist.begin();
-      sethba.settings() = (*it);
-    } else {
+	if (getMode()) {
+		// GET
+		if (realDelays) {
+			RSPReadhbaEvent readhba;
+			readhba.timestamp = Timestamp(0,0);
+			readhba.rcumask = getRCUMask();
+			readhba.cache = true;
 
-      // clear first
-      sethba.settings() = 0;
+			m_rspport.send(readhba);
+		}
+		else {
+			RSPGethbaEvent gethba;
+			gethba.timestamp = Timestamp(0,0);
+			gethba.rcumask = getRCUMask();
+			gethba.cache = false;
 
-      int i = 0;
-      std::list<int>::iterator it;
-      for (it = m_delaylist.begin(); it != m_delaylist.end(); it++, i++) {
-	if (i >= MEPHeader::N_HBA_DELAYS) break;
-	  sethba.settings()(Range::all(), i) = (*it);
-      }
-    }
+			m_rspport.send(gethba);
+		}
+	}
+	else { // SET
+		// Note: also accept the 'set'-form for the readHBA command
+		//       why bother the user if we know what he realy ment
+		RSPSethbaEvent sethba;
+		sethba.timestamp = Timestamp(0,0);
+		sethba.rcumask = getRCUMask();
+
+		sethba.settings().resize(sethba.rcumask.count(), MEPHeader::N_HBA_DELAYS);
+
+		if (1 == m_delaylist.size()) {
+			std::list<int>::iterator it = m_delaylist.begin();
+			sethba.settings() = (*it);
+		} 
+		else {
+			// clear first
+			sethba.settings() = 0;
+
+			int i = 0;
+			std::list<int>::iterator it;
+			for (it = m_delaylist.begin(); it != m_delaylist.end(); it++, i++) {
+				if (i >= MEPHeader::N_HBA_DELAYS) 
+					break;
+				sethba.settings()(Range::all(), i) = (*it);
+			}
+		}
 #if 0
-    for (int i = 0; i < sethba.settings().extent(firstDim); i++) {
-      printf("delays(%d)=", i);
-      cout << sethba.settings()(i) << endl;
-    }
+		for (int i = 0; i < sethba.settings().extent(firstDim); i++) {
+			printf("delays(%d)=", i);
+			cout << sethba.settings()(i) << endl;
+		}
 #endif
-
-    m_rspport.send(sethba);
-  }
+		m_rspport.send(sethba);
+	}
 }
 
 GCFEvent::TResult HBACommand::ack(GCFEvent& e)
 {
-  switch (e.signal)
-  {
-    case RSP_GETHBAACK:
-    {
-      RSPGethbaackEvent ack(e);
-      bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
-
-      cout << "settings().shape()=" << ack.settings().shape() << endl;
-
-      if (SUCCESS == ack.status)
-      {
-        int hbain = 0;
-        for (int hbaout = 0; hbaout < get_ndevices(); hbaout++) {
-
-          if (mask[hbaout]) {
-            logMessage(cout, formatString("HBA[%2d].delays=", hbaout));
-	    for (int i = 0; i < MEPHeader::N_HBA_DELAYS; i++) {
-	      logMessage(cout, formatString("%3d", (int)(ack.settings()(hbain, i))));
-	    }
-	    hbain++;
-          }
-        }
-      }
-      else
-      {
-        logMessage(cerr,"Error: RSP_GETHBA command failed.");
-      }
-    }
-    break;
+	switch (e.signal) {
+	case RSP_GETHBAACK:
+	{
+		RSPGethbaackEvent ack(e);
+		bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
+
+		cout << "settings().shape()=" << ack.settings().shape() << endl;
+
+		if (SUCCESS == ack.status) {
+			int hbain = 0;
+			for (int hbaout = 0; hbaout < get_ndevices(); hbaout++) {
+				if (mask[hbaout]) {
+					cout << formatString("HBA[%2d].delays=", hbaout);
+					for (int i = 0; i < MEPHeader::N_HBA_DELAYS; i++) {
+						cout << formatString(" %3d", (int)(ack.settings()(hbain, i)));
+					}
+					cout << endl;
+					hbain++;
+				}
+			}
+		}
+		else {
+			logMessage(cerr,"Error: RSP_GETHBA command failed.");
+		}
+	}
+	break;
 
-    case RSP_SETHBAACK:
-    {
-      RSPSethbaackEvent ack(e);
+	case RSP_READHBAACK:
+	{
+		RSPReadhbaackEvent ack(e);
+		bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
+
+		cout << "settings().shape()=" << ack.settings().shape() << endl;
+
+		if (SUCCESS == ack.status) {
+			int hbain = 0;
+			for (int hbaout = 0; hbaout < get_ndevices(); hbaout++) {
+				if (mask[hbaout]) {
+					cout << formatString("HBA[%2d].real delays=", hbaout);
+					for (int i = 0; i < MEPHeader::N_HBA_DELAYS; i++) {
+						if ((int)(ack.settings()(hbain, i)) == 255) {
+							cout << " ???";
+						}
+						else  {
+							cout << formatString(" %3d", (int)(ack.settings()(hbain, i)));
+						}
+					}
+					cout << endl;
+					hbain++;
+				}
+			}
+		}
+		else {
+			logMessage(cerr,"Error: RSP_READHBA command failed.");
+		}
+	}
+	break;
 
-      if (SUCCESS != ack.status)
-      {
-        logMessage(cerr,"Error: RSP_SETHBA command failed.");
-      }
-    }
-  }
+	case RSP_SETHBAACK:
+	{
+		RSPSethbaackEvent ack(e);
+		if (SUCCESS != ack.status) {
+			logMessage(cerr,"Error: RSP_SETHBA command failed.");
+		}
+	}
+	break;
+	}
 
-  GCFTask::stop();
+	GCFTask::stop();
 
-  return GCFEvent::HANDLED;
+	return (GCFEvent::HANDLED);
 }
 
 //
@@ -2100,6 +2138,7 @@ RSPCtl::~RSPCtl()
 
 GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port)
 {
+	LOG_DEBUG_STR ("initial:" << eventName(e) << "@" << port.getName());
   GCFEvent::TResult status = GCFEvent::HANDLED;
 
   switch(e.signal)
@@ -2163,120 +2202,114 @@ GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port)
 
 GCFEvent::TResult RSPCtl::docommand(GCFEvent& e, GCFPortInterface& port)
 {
-  GCFEvent::TResult status = GCFEvent::HANDLED;
+	LOG_DEBUG_STR ("docommand:" << eventName(e) << "@" << port.getName());
 
-  switch (e.signal)
-    {
-    case F_ENTRY:
-      {
-	m_subclock.send(); // subscribe to clock updates
-	// after receiving the clock update execute the actual requested command
-      }
-      break;
+	GCFEvent::TResult status = GCFEvent::HANDLED;
 
-    case F_CONNECTED:
-      {
-	// connection with te frontend! send the command to the rsp driver
-	FECommand* feCommand = dynamic_cast<FECommand*>(m_command);
-	if(feCommand != 0)
-	  {
-	    if(feCommand->isConnected(port))
-	      {
-		m_command->send();
-	      }
-	  }
-      }
-      break;
-    
-    case F_DISCONNECTED:
-      {
-	port.close();
-	logMessage(cerr,formatString("Error: port '%s' disconnected.",port.getName().c_str()));
-	exit(EXIT_FAILURE);
-      }
-      break;
+	switch (e.signal) {
+	case F_ENTRY:
+	{
+		m_subclock.send(); // subscribe to clock updates
+		// after receiving the clock update execute the actual requested command
+	}
+	break;
 
-    case RSP_GETRCUACK:
-    case RSP_SETRCUACK:
-    case RSP_SETRSUACK:
-    case RSP_GETSTATSACK:
-    case RSP_SUBSTATSACK:
-    case RSP_UPDSTATS:
-    case RSP_SUBXCSTATSACK:
-    case RSP_UPDXCSTATS:
-    case RSP_GETVERSIONACK:
-    case RSP_GETSUBBANDSACK:
-    case RSP_SETSUBBANDSACK:
-    case RSP_SETWEIGHTSACK:
-    case RSP_GETWEIGHTSACK:
-    case RSP_GETWGACK:
-    case RSP_SETWGACK:
-    case RSP_SETCLOCKACK:
-    case RSP_GETSTATUSACK:
-    case RSP_GETTDSTATUSACK:
-    case RSP_SUBREGISTERSTATEACK:
-    case RSP_UPDREGISTERSTATE:
-    case RSP_SETHBAACK:
-    case RSP_GETHBAACK:
-    case RSP_SETTBBACK:
-    case RSP_GETTBBACK:
-    case RSP_GETBYPASSACK:
-    case RSP_SETBYPASSACK:
-      status = m_command->ack(e); // handle the acknowledgement
-      break;
+	case F_CONNECTED:
+	{
+		// connection with te frontend! send the command to the rsp driver
+		FECommand* feCommand = dynamic_cast<FECommand*>(m_command);
+		if(feCommand != 0) {
+			if(feCommand->isConnected(port)) {
+				m_command->send();
+			}
+		}
+	}
+	break;
 
-    case RSP_UPDCLOCK:
-    case RSP_SUBCLOCKACK:
-    case RSP_GETCLOCKACK:
-      {
-	status = m_subclock.ack(e); // handle clock updates
+	case F_DISCONNECTED:
+	{
+		port.close();
+		logMessage(cerr,formatString("Error: port '%s' disconnected.",port.getName().c_str()));
+		exit(EXIT_FAILURE);
+	}
+	break;
 
-	if (RSP_GETCLOCKACK == e.signal) {
+	case RSP_GETRCUACK:
+	case RSP_SETRCUACK:
+	case RSP_SETRSUACK:
+	case RSP_GETSTATSACK:
+	case RSP_SUBSTATSACK:
+	case RSP_UPDSTATS:
+	case RSP_SUBXCSTATSACK:
+	case RSP_UPDXCSTATS:
+	case RSP_GETVERSIONACK:
+	case RSP_GETSUBBANDSACK:
+	case RSP_SETSUBBANDSACK:
+	case RSP_SETWEIGHTSACK:
+	case RSP_GETWEIGHTSACK:
+	case RSP_GETWGACK:
+	case RSP_SETWGACK:
+	case RSP_SETCLOCKACK:
+	case RSP_GETSTATUSACK:
+	case RSP_GETTDSTATUSACK:
+	case RSP_SUBREGISTERSTATEACK:
+	case RSP_UPDREGISTERSTATE:
+	case RSP_SETHBAACK:
+	case RSP_GETHBAACK:
+	case RSP_READHBAACK:
+	case RSP_SETTBBACK:
+	case RSP_GETTBBACK:
+	case RSP_GETBYPASSACK:
+	case RSP_SETBYPASSACK:
+		status = m_command->ack(e); // handle the acknowledgement
+	break;
 
-	  // reparse options
-	  if (0 == (m_command = parse_options(m_argc, m_argv)))
-	    {
-	      logMessage(cerr,"Warning: no command specified.");
-	      usage();
-	      exit(EXIT_FAILURE);
-	    }
-	  // check if a connection must be made with a frontend. If so, connect first
-	  // and send the command to the rspdriver when connected with the frontend
-	  FECommand* feCommand = dynamic_cast<FECommand*>(m_command);
-	  if(feCommand != 0)
-	    {
-	      if(feCommand->isFrontEndSet())
-		{
-		  feCommand->connect(*this);
-		}
-	      else
-		{
-		  m_command->send();
+	case RSP_UPDCLOCK:
+	case RSP_SUBCLOCKACK:
+	case RSP_GETCLOCKACK:
+	{
+		status = m_subclock.ack(e); // handle clock updates
+
+		if (RSP_GETCLOCKACK == e.signal) {
+			// reparse options
+			if (0 == (m_command = parse_options(m_argc, m_argv))) {
+				logMessage(cerr,"Warning: no command specified.");
+				usage();
+				exit(EXIT_FAILURE);
+			}
+			// check if a connection must be made with a frontend. If so, connect first
+			// and send the command to the rspdriver when connected with the frontend
+			FECommand* feCommand = dynamic_cast<FECommand*>(m_command);
+			if(feCommand != 0) {
+				if(feCommand->isFrontEndSet()) {
+					feCommand->connect(*this);
+				}
+				else {
+					m_command->send();
+				}
+			}
+			else {
+				m_command->send();
+			}
 		}
-	    }
-	  else
-	    {
-	      m_command->send();
-	    }
 	}
-      }
-      break;
+	break;
 
 #ifdef ENABLE_RSPFE
-    case RSPFE_STOP_RSPCTL:
-      logMessage(cout,"Rspctl stopped by frontend.");
-      m_command->stop();
-      GCFTask::stop();
-      break;
+	case RSPFE_STOP_RSPCTL:
+		logMessage(cout,"Rspctl stopped by frontend.");
+		m_command->stop();
+		GCFTask::stop();
+	break;
 #endif
 
-    default:
-      logMessage(cerr,"Error: unhandled event.");
-      GCFTask::stop();
-      break;
-    }
+	default:
+		logMessage(cerr,"Error: unhandled event.");
+		GCFTask::stop();
+		break;
+	}
 
-  return status;
+	return status;
 }
 
 void RSPCtl::mainloop()
@@ -2289,17 +2322,10 @@ static void usage()
 {
   cout << "rspctl usage:" << endl;
   cout << endl;
-  cout << "rspctl --weights                    [--select=<set>]  # get weights as complex values" << endl;
-  cout << "  Example --weights --select=1,2,4:7 or --select=1:3,5:7" << endl;
-  cout << "rspctl --weights=value.re[,value.im][--select=<set>][--beamlets=<set>] # set weights as complex value" << endl;
-  cout << "rspctl --aweights                   [--select=<set>]  # get weights as power and angle (in degrees)" << endl;
-  cout << "rspctl --aweights=amplitude[,angle] [--select=<set>]  # set weights as amplitude and angle (in degrees)" << endl;
-  cout << "rspctl --subbands                   [--select=<set>]  # get subband selection" << endl;
-  cout << "rspctl --subbands=<set>             [--select=<set>]  # set subband selection" << endl;
-  cout << "  Example --subbands sets: --subbands=0:39 or --select=0:19,40:59" << endl;
+  cout << "--- RCU control ----------------------------------------------------------------------------------------------" << endl;
   cout << "rspctl --rcu                        [--select=<set>]  # show current rcu control setting" << endl;
   cout << "rspctl --rcu=0x00000000             [--select=<set>]  # set the rcu control registers" << endl;
-  cout << "     mask      value    " << endl;
+  cout << "  mask       value    " << endl;
   cout << "  0x0000007F INPUT_DELAY  Sample delay for the data from the RCU." << endl;
   cout << "  0x00000080 INPUT_ENABLE Enable RCU input." << endl;
   cout << endl;
@@ -2310,10 +2336,10 @@ static void usage()
   cout << "  0x00001000 HB-SEL-0     HBA filter selection" << endl;
   cout << "  0x00002000 HB-SEL-1     HBA filter selection" << endl;
   cout << "                Options : HBA-SEL-0 HBA-SEL-1 Function" << endl;
-  cout << "                             0          0      210-270 MHz" << endl;
-  cout << "                             0          1      170-230 MHz" << endl;
-  cout << "                             1          0      110-190 MHz" << endl;
-  cout << "                             1          1      all off" << endl;
+  cout << "                            0          0      210-270 MHz" << endl;
+  cout << "                            0          1      170-230 MHz" << endl;
+  cout << "                            1          0      110-190 MHz" << endl;
+  cout << "                            1          1      all off" << endl;
   cout << "  0x00004000 VL-EN        low band supply on (1) or off (0)" << endl;
   cout << "  0x00008000 VH-EN        high band supply on (1) or off (0)" << endl;
   cout << endl;
@@ -2357,10 +2383,30 @@ static void usage()
   cout << "       --rcudelay=[0..127]       # set the delay for rcu's" << endl;
   cout << "       --rcuenable[=0]           # enable (or disable) input from RCU's" << endl;
   cout << endl;
-  cout << "rspctl --wg                  [--select=<set>]  # get waveform generator settings" << endl;
+  cout << "rspctl --specinv[=0] [--select=<set>] # enable (or disable) spectral inversion" << endl;
+  cout << endl;
+  cout << "--- Signalprocessing -----------------------------------------------------------------------------------------" << endl;
+  cout << "rspctl --weights                    [--select=<set>]  # get weights as complex values" << endl;
+  cout << "  Example --weights --select=1,2,4:7 or --select=1:3,5:7" << endl;
+  cout << "rspctl --weights=value.re[,value.im][--select=<set>][--beamlets=<set>] # set weights as complex value" << endl;
+  cout << "rspctl --aweights                   [--select=<set>]  # get weights as power and angle (in degrees)" << endl;
+  cout << "rspctl --aweights=amplitude[,angle] [--select=<set>]  # set weights as amplitude and angle (in degrees)" << endl;
+  cout << "rspctl --subbands                   [--select=<set>]  # get subband selection" << endl;
+  cout << "rspctl --subbands=<set>             [--select=<set>]  # set subband selection" << endl;
+  cout << "  Example --subbands sets: --subbands=0:39 or --select=0:19,40:59" << endl;
+  cout << "rspctl --xcsubband                                    # get the subband selection for cross correlation" << endl;
+  cout << "rspctl --xcsubband=<int>                              # set the subband to cross correlate" << endl;
+  cout << "rspctl --wg                         [--select=<set>]  # get waveform generator settings" << endl;
   cout << "rspctl --wg=freq [--phase=..] [--amplitude=..] [--select=<set>]  # set waveform generator settings" << endl;
+  cout << endl;
+  cout << "--- Status info ----------------------------------------------------------------------------------------------" << endl;
+  cout << "rspctl --version             [--select=<set>]  # get version information" << endl;
   cout << "rspctl --status              [--select=<set>]  # get status of RSP boards" << endl;
   cout << "rspctl --tdstatus            [--select=<set>]  # get status of TD boards" << endl;
+  cout << "rspctl --realdelays[=<list>] [--select=<set>]  # get the installed 16 delays of one or more HBA's" << endl;
+  cout << "rspctl --regstate                              # show update status of all registers once every second" << endl;
+  cout << endl;
+  cout << "--- Statistics -----------------------------------------------------------------------------------------------" << endl;
   cout << "rspctl --statistics[=(subband|beamlet)]        # get subband (default) or beamlet statistics" << endl;
   cout << "             [--select=<set>]                  #" << endl;
   cout << "             [--duration=<seconds>]            #" << endl;
@@ -2376,658 +2422,651 @@ static void usage()
 #ifdef ENABLE_RSPFE
   cout << "             [--feport=<hostname>:<port>]      #" << endl;
 #endif
-  cout << "rspctl --xcsubband                             # get the subband selection for cross correlation" << endl;
-  cout << "rspctl --xcsubband=<int>                       # set the subband to cross correlate" << endl;
+  cout << endl;
+  cout << "--- Miscellaneous --------------------------------------------------------------------------------------------" << endl;
   cout << "rspctl --clock[=<int>]                         # get or set the clock frequency of clocks in MHz" << endl;
+  cout << "rspctl --rspclear           [--select=<set>]   # clear FPGA registers on RSPboard" << endl;
   cout << "rspctl --hbadelays[=<list>] [--select=<set>]   # set or get the 16 delays of one or more HBA's" << endl;
   cout << "rspctl --tbbmode[=transient | =subbands,<set>] # set or get TBB mode, 'transient' or 'subbands', if subbands then specify subband set" << endl;
-  cout << "rspctl --version            [--select=<set>]   # get version information" << endl;
-  cout << "rspctl --rspclear           [--select=<set>]   # clear FPGA registers on RSPboard" << endl;
-  cout << "rspctl --regstate                              # show update status of all registers once every second" << endl;
-  cout << "rspctl --specinv[=0]        [--select=<set>]   # enable (or disable) spectral inversion" << endl;
 }
 
 Command* RSPCtl::parse_options(int argc, char** argv)
 {
-  Command*    command        = 0;
-  RCUCommand* rcumodecommand = 0;
-  HBACommand* hbacommand     = 0;
-  list<int> select;
-  list<int> beamlets;
-  bool xcangle = false;
+	Command*    command        = 0;
+	RCUCommand* rcumodecommand = 0;
+	HBACommand* hbacommand     = 0;
+	list<int> 	select;
+	list<int> 	beamlets;
+	bool 		xcangle = false;
 
-  // select all by default
-  select.clear();
-  for (int i = 0; i < MEPHeader::MAX_N_RCUS; ++i) select.push_back(i);
+	// select all by default
+	select.clear();
+	for (int i = 0; i < MEPHeader::MAX_N_RCUS; ++i) 
+		select.push_back(i);
 
 	beamlets.clear();
-  for (int i = 0; i < MEPHeader::N_BEAMLETS; ++i) beamlets.push_back(i);
-  	
-  optind = 0; // reset option parsing
-  //opterr = 0; // no error reporting to stderr
-  while (1) {
-      static struct option long_options[] = {
-	  { "select",         required_argument, 0, 'l' },
-	  { "beamlets",       required_argument, 0, 'b' },
-	  { "weights",        optional_argument, 0, 'w' },
-	  { "aweights",       optional_argument, 0, 'a' },
-	  { "subbands",       optional_argument, 0, 's' },
-	  { "rcu",            optional_argument, 0, 'r' },
-	  { "rcumode",        required_argument, 0, 'm' },
-	  { "rcuprsg",        optional_argument, 0, 'p' },
-	  { "rcureset",       optional_argument, 0, 'e' },
-	  { "rcuattenuation", required_argument, 0, 'n' },
-	  { "rcudelay",       required_argument, 0, 'y' },
-    { "rcuenable",      optional_argument, 0, 'E' },
-	  { "wg",             optional_argument, 0, 'g' },
-	  { "wgmode",         required_argument, 0, 'G' },
-	  { "amplitude",      required_argument, 0, 'A' },
-	  { "phase",          required_argument, 0, 'P' },
-	  { "status",         no_argument,       0, 'q' },
-	  { "tdstatus",       no_argument,       0, 'Q' },
-	  { "statistics",     optional_argument, 0, 't' },
-	  { "xcstatistics",   no_argument,       0, 'x' },
-	  { "xcangle",        no_argument,       0, 'B' },
-	  { "xcsubband",      optional_argument, 0, 'z' },
-	  { "clock",          optional_argument, 0, 'c' },
-	  { "hbadelays",      optional_argument, 0, 'H' },
-	  { "tbbmode",        optional_argument, 0, 'T' },
-	  { "version",        no_argument,       0, 'v' },
-	  //	  { "rspreset",       optional_argument, 0, 'R' },
-	  { "rspclear",       optional_argument, 0, 'C' },
-	  { "regstate",       no_argument,       0, 'S' },
-	  { "help",           no_argument,       0, 'h' },
+	for (int i = 0; i < MEPHeader::N_BEAMLETS; ++i) 
+		beamlets.push_back(i);
+
+	optind = 0; // reset option parsing
+	//opterr = 0; // no error reporting to stderr
+	static struct option long_options[] = {
+		{ "aweights",       optional_argument, 0, 'a' },
+		{ "beamlets",       required_argument, 0, 'b' },
+		{ "clock",          optional_argument, 0, 'c' },
+		{ "duration",       required_argument, 0, 'd' },
+		{ "rcureset",       optional_argument, 0, 'e' },
 #ifdef ENABLE_RSPFE
-	  { "feport",         required_argument, 0, 'f' },
+		{ "feport",         required_argument, 0, 'f' },
 #endif
-	  { "duration",       required_argument, 0, 'd' },
-	  { "integration",    required_argument, 0, 'i' },
-	  { "specinv",	      optional_argument, 0, 'I' },
-//	  { "instance",       required_argument, 0, 'I' },
-	  { "directory"  ,    required_argument, 0, 'D' },
-
-	  { 0, 0, 0, 0 },
+		{ "wg",             optional_argument, 0, 'g' },
+		{ "help",           no_argument,       0, 'h' },
+		{ "integration",    required_argument, 0, 'i' },
+		{ "select",         required_argument, 0, 'l' },
+		{ "rcumode",        required_argument, 0, 'm' },
+		{ "rcuattenuation", required_argument, 0, 'n' },
+		{ "rcuprsg",        optional_argument, 0, 'p' },
+		{ "status",         no_argument,       0, 'q' },
+		{ "rcu",            optional_argument, 0, 'r' },
+		{ "subbands",       optional_argument, 0, 's' },
+		{ "statistics",     optional_argument, 0, 't' },
+		{ "version",        no_argument,       0, 'v' },
+		{ "weights",        optional_argument, 0, 'w' },
+		{ "xcstatistics",   no_argument,       0, 'x' },
+		{ "rcudelay",       required_argument, 0, 'y' },
+		{ "xcsubband",      optional_argument, 0, 'z' },
+
+		{ "amplitude",      required_argument, 0, 'A' },
+		{ "xcangle",        no_argument,       0, 'B' },
+		{ "rspclear",       optional_argument, 0, 'C' },
+		{ "directory"  ,    required_argument, 0, 'D' },
+		{ "rcuenable",      optional_argument, 0, 'E' },
+		{ "wgmode",         required_argument, 0, 'G' },
+		{ "hbadelays",      optional_argument, 0, 'H' },
+		{ "specinv",	    optional_argument, 0, 'I' },
+		{ "phase",          required_argument, 0, 'P' },
+		{ "tdstatus",       no_argument,       0, 'Q' },
+//		{ "rspreset",       optional_argument, 0, 'R' },
+		{ "realdelays",     optional_argument, 0, 'R' },
+		{ "regstate",       no_argument,       0, 'S' },
+		{ "tbbmode",        optional_argument, 0, 'T' },
+
+		{ 0, 0, 0, 0 },
 	};
 
-      int option_index = 0;
-      int c = getopt_long(argc, argv,
-			  "l:b:w::a::s::r::g::qQt::xz::vc::hf:d:i:I:", long_options, &option_index);
+	realDelays = false;
+	while (1) {
+		int option_index = 0;
+		int c = getopt_long(argc, argv, "l:b:w::a::s::r::g::qQt::xz::vc::hf:d:i:I:", long_options, &option_index);
 
-      if (c == -1)
-	break;
+		if (c == -1)	// end of argument list reached?
+			break;
 
-      switch (c)
-	{
-	case 'l': 	// --select
-	  if (optarg) {
-	      if (!command || 0 == command->get_ndevices()) {
-		  logMessage(cerr,"Error: 'command' argument should come before --select argument");
-		  exit(EXIT_FAILURE);
-	      }
-	      select = strtolist(optarg, command->get_ndevices());
-	      if (select.empty()) {
-		  logMessage(cerr,"Error: invalid or missing '--select' option");
-		  exit(EXIT_FAILURE);
-	      }
-	  }
-	  else {
-	      logMessage(cerr,"Error: option '--select' requires an argument");
-	  }
-	  break;
+		switch (c) {
+		case 'l': 	// --select
+			if (optarg) {
+				if (!command || 0 == command->get_ndevices()) {
+					logMessage(cerr,"Error: 'command' argument should come before --select argument");
+					exit(EXIT_FAILURE);
+				}
+				select = strtolist(optarg, command->get_ndevices());
+				if (select.empty()) {
+					logMessage(cerr,"Error: invalid or missing '--select' option");
+					exit(EXIT_FAILURE);
+				}
+			}
+			else {
+				logMessage(cerr,"Error: option '--select' requires an argument");
+			}
+		break;
 
-	case 'b': 	// --beamlets
-	  if (optarg) {
-	      if (!command || 0 == command->get_ndevices()) {
-		  logMessage(cerr,"Error: 'command' argument should come before --beamlets argument");
-		  exit(EXIT_FAILURE);
-	      }
-	      beamlets = strtolist(optarg, MEPHeader::N_BEAMLETS);
-	      if (beamlets.empty()) {
-		  logMessage(cerr,"Error: invalid or missing '--beamlets' option");
-		  exit(EXIT_FAILURE);
-	      }
-	      
-	  }
-	  else {
-	      logMessage(cerr,"Error: option '--beamlets' requires an argument");
-	  }
-	  break;
-
-
-	case 'w':	// --weights
-	  {
-	    if (command)
-	      delete command;
-	    WeightsCommand* weightscommand = new WeightsCommand(m_server);
-	    weightscommand->setType(WeightsCommand::COMPLEX);
-	    command = weightscommand;
-
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		weightscommand->setMode(false);
-		double re = 0.0, im = 0.0;
-		int numitems = sscanf(optarg, "%lf,%lf", &re, &im);
-		if (numitems == 0 || numitems == EOF) {
-		  logMessage(cerr,"Error: invalid weights value. Should be of the format "
-			     "'--weights=value.re[,value.im]' where value is a floating point value in the range (-1,1].");
-		  exit(EXIT_FAILURE);
-		}
-		weightscommand->setValue(complex<double>(re,im));
-	      }
-	  }
-	  break;
-
-	case 'a':	// --aweights
-	  {
-	    if (command)
-	      delete command;
-	    WeightsCommand* weightscommand = new WeightsCommand(m_server);
-	    weightscommand->setType(WeightsCommand::ANGLE);
-	    command = weightscommand;
-
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		weightscommand->setMode(false);
-		double amplitude = 0.0, angle = 0.0;
-		int numitems = sscanf(optarg, "%lf,%lf", &amplitude, &angle);
-		if (numitems == 0 || numitems == EOF) {
-		  logMessage(cerr,"Error: invalid aweights value. Should be of the format "
-			     "'--weights=amplitude[,angle]' where angle is in degrees.");
-		  exit(EXIT_FAILURE);
+		case 'b': 	// --beamlets
+			if (optarg) {
+				if (!command || 0 == command->get_ndevices()) {
+					logMessage(cerr,"Error: 'command' argument should come before --beamlets argument");
+					exit(EXIT_FAILURE);
+				}
+				beamlets = strtolist(optarg, MEPHeader::N_BEAMLETS);
+				if (beamlets.empty()) {
+					logMessage(cerr,"Error: invalid or missing '--beamlets' option");
+					exit(EXIT_FAILURE);
+				}
+			}
+			else {
+				logMessage(cerr,"Error: option '--beamlets' requires an argument");
+			}
+		break;
+
+		case 'w':	// --weights
+		{
+			if (command)
+				delete command;
+			WeightsCommand* weightscommand = new WeightsCommand(m_server);
+			weightscommand->setType(WeightsCommand::COMPLEX);
+			command = weightscommand;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				weightscommand->setMode(false);
+				double re = 0.0, im = 0.0;
+				int numitems = sscanf(optarg, "%lf,%lf", &re, &im);
+				if (numitems == 0 || numitems == EOF) {
+					logMessage(cerr,"Error: invalid weights value. Should be of the format "
+					"'--weights=value.re[,value.im]' where value is a floating point value in the range (-1,1].");
+					exit(EXIT_FAILURE);
+				}
+				weightscommand->setValue(complex<double>(re,im));
+			}
 		}
-	  
-		if (angle < -180.0 || angle > 180.0) {
-		  logMessage(cerr, "Error: invalid angle, should be between -180 < angle < 180.0.");
-		  exit(EXIT_FAILURE);
+		break;
+
+		case 'a':	// --aweights
+		{
+			if (command)
+				delete command;
+			WeightsCommand* weightscommand = new WeightsCommand(m_server);
+			weightscommand->setType(WeightsCommand::ANGLE);
+			command = weightscommand;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				weightscommand->setMode(false);
+				double amplitude = 0.0, angle = 0.0;
+				int numitems = sscanf(optarg, "%lf,%lf", &amplitude, &angle);
+				if (numitems == 0 || numitems == EOF) {
+					logMessage(cerr,"Error: invalid aweights value. Should be of the format "
+					"'--weights=amplitude[,angle]' where angle is in degrees.");
+					exit(EXIT_FAILURE);
+				}
+
+				if (angle < -180.0 || angle > 180.0) {
+					logMessage(cerr, "Error: invalid angle, should be between -180 < angle < 180.0.");
+					exit(EXIT_FAILURE);
+				}
+
+				//weightscommand->setValue(complex<double>(amplitude * ::cos(angle), amplitude * ::sin(angle)));
+				weightscommand->setValue(amplitude * exp(complex<double>(0,angle / 180.0 * M_PI)));
+			}
 		}
-	  
-		//weightscommand->setValue(complex<double>(amplitude * ::cos(angle), amplitude * ::sin(angle)));
-		weightscommand->setValue(amplitude * exp(complex<double>(0,angle / 180.0 * M_PI)));
-	      }
-	  }
-	  break;
-
-	case 's':	// --subbands
-	  {
-	    if (command)
-	      delete command;
-	    SubbandsCommand* subbandscommand = new SubbandsCommand(m_server);
-	    subbandscommand->setType(SubbandSelection::BEAMLET);
-
-	    command = subbandscommand;
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		subbandscommand->setMode(false);
-		list<int> subbandlist = strtolist(optarg, MEPHeader::N_SUBBANDS);
-		if (subbandlist.empty()) {
-		    logMessage(cerr,"Error: invalid or empty '--subbands' option");
-		    exit(EXIT_FAILURE);
+		break;
+
+		case 's':	// --subbands
+		{
+			if (command)
+				delete command;
+			SubbandsCommand* subbandscommand = new SubbandsCommand(m_server);
+			subbandscommand->setType(SubbandSelection::BEAMLET);
+
+			command = subbandscommand;
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				subbandscommand->setMode(false);
+				list<int> subbandlist = strtolist(optarg, MEPHeader::N_SUBBANDS);
+				if (subbandlist.empty()) {
+					logMessage(cerr,"Error: invalid or empty '--subbands' option");
+					exit(EXIT_FAILURE);
+				}
+				subbandscommand->setSubbandList(subbandlist);
+			}
 		}
-		subbandscommand->setSubbandList(subbandlist);
-	    }
-	  }
-	  break;
-
-	case 'r': // --rcu
-	  {
-	    if (command)
-	      delete command;
-	    RCUCommand* rcucommand = new RCUCommand(m_server);
-	    command = rcucommand;
-
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		rcucommand->setMode(false);
-		unsigned long controlopt = strtoul(optarg, 0, 0);
-		if ( controlopt > 0xFFFFFFFF ) {
-		    logMessage(cerr,"Error: option '--rcu' parameter must be < 0xFFFFFFFF");
-		    delete command;
-		    return 0;
+		break;
+
+		case 'r': // --rcu
+		{
+			if (command)
+				delete command;
+			RCUCommand* rcucommand = new RCUCommand(m_server);
+			command = rcucommand;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				rcucommand->setMode(false);
+				unsigned long controlopt = strtoul(optarg, 0, 0);
+				if (controlopt > 0xFFFFFFFF) {
+					logMessage(cerr,"Error: option '--rcu' parameter must be < 0xFFFFFFFF");
+					delete command;
+					return 0;
+				}
+
+				rcucommand->control().setRaw((uint32)controlopt);
+			}
 		}
+		break;
 
-		rcucommand->control().setRaw((uint32)controlopt);
-	    }
-	  }
-	  break;
-
-	case 'm': // --rcumode
-	case 'p': // --rcuprsg
-	case 'e': // --rcureset
-	case 'n': // --rcuattenuation
-//	case 'u': // --rcuspecinv
-	case 'y': // --rcudelay
-        case 'E': // --rcuenable
-	  {
-	    // instantiate once, then reuse to add control bits
-	    if (!rcumodecommand) {
-	      if (command) delete command;
-	      rcumodecommand = new RCUCommand(m_server);
-	    }
+		case 'm': // --rcumode
+		case 'p': // --rcuprsg
+		case 'e': // --rcureset
+		case 'n': // --rcuattenuation
+		case 'y': // --rcudelay
+		case 'E': // --rcuenable
+		{
+			// instantiate once, then reuse to add control bits
+			if (!rcumodecommand) {
+				if (command) 
+					delete command;
+				rcumodecommand = new RCUCommand(m_server);
+			}
 
-	    command = rcumodecommand;
-	    command->set_ndevices(m_nrcus);
+			command = rcumodecommand;
+			command->set_ndevices(m_nrcus);
 
-	    if ('m' == c || 'n' == c || 'y' == c) {
-	      if (!optarg) {
-		logMessage(cerr,"Error: option requires an argument");
-		delete command;
-		return 0;
-	      }
-	    }
+			if ('m' == c || 'n' == c || 'y' == c) {
+				if (!optarg) {
+					logMessage(cerr,"Error: option requires an argument");
+					delete command;
+					return 0;
+				}
+			}
 
-	    rcumodecommand->setMode(false);
-	    unsigned long controlopt = 0;
+			rcumodecommand->setMode(false);
+			unsigned long controlopt = 0;
 
-	    switch (c) {
+			switch (c) {
+			case 'm': // --rcumode
+				controlopt = strtoul(optarg, 0, 0);
+				if (controlopt >= 8) {
+					logMessage(cerr,"Error: --rcumode value should be < 8");
+					delete command;
+					return 0;
+				}
+				rcumodecommand->control().setMode((RCUSettings::Control::RCUMode)controlopt);
+			break;
 
-	    case 'm': // --rcumode
-	      controlopt = strtoul(optarg, 0, 0);
-	      if (controlopt >= 8) {
-		logMessage(cerr,"Error: --rcumode value should be < 8");
-		delete command;
-		return 0;
-	      }
-	      rcumodecommand->control().setMode((RCUSettings::Control::RCUMode)controlopt);
-	      break;
+			case 'p': // --rcuprsg
+				if (optarg && !strncmp(optarg, "0", 1)) {
+					rcumodecommand->control().setPRSG(false);
+				} else {
+					rcumodecommand->control().setPRSG(true);
+				}
+			break;
 
-	    case 'p': // --rcuprsg
-	      if (optarg && !strncmp(optarg, "0", 1)) {
-		rcumodecommand->control().setPRSG(false);
-	      } else {
-		rcumodecommand->control().setPRSG(true);
-	      }
-	      break;
+			case 'e': // --rcureset
+				if (optarg && !strncmp(optarg, "0", 1)) {
+					rcumodecommand->control().setReset(false);
+				} else {
+					rcumodecommand->control().setReset(true);
+				}
+			break;
 
-	    case 'e': // --rcureset
-	      if (optarg && !strncmp(optarg, "0", 1)) {
-		rcumodecommand->control().setReset(false);
-	      } else {
-		rcumodecommand->control().setReset(true);
-	      }
-	      break;
-
-	    case 'n': // --rcuattenuation
-	      controlopt = strtoul(optarg, 0, 0);
-	      if (controlopt > 31) {
-		logMessage(cerr,"Error: --rcuattenuation value should be <= 31");
-		delete command;
-		return 0;
-	      }
-	      rcumodecommand->control().setAttenuation((uint8)controlopt);
-	      break;
-
-//	    case 'u': // --rcuspecinv
-//	      if (optarg && !strncmp(optarg, "0", 1)) {
-//		rcumodecommand->control().setSpecinv(false);
-//	      } else {
-//		rcumodecommand->control().setSpecinv(true);
-//	      }
-//	      break;
-
-	    case 'y': // --rcudelay
-	      controlopt = strtoul(optarg, 0, 0);
-	      if (controlopt > 127) {
-		logMessage(cerr,"Error: --rcudelay value should be <= 127");
-		delete command;
-		return 0;
-	      }
-	      rcumodecommand->control().setDelay((uint8)controlopt);
-	      break;
+			case 'n': // --rcuattenuation
+				controlopt = strtoul(optarg, 0, 0);
+				if (controlopt > 31) {
+					logMessage(cerr,"Error: --rcuattenuation value should be <= 31");
+					delete command;
+					return 0;
+				}
+				rcumodecommand->control().setAttenuation((uint8)controlopt);
+			break;
 
-            case 'E': // --rcuenable
-	      if (optarg && !strncmp(optarg, "0", 1)) {
-		rcumodecommand->control().setEnable(false);
-	      } else {
-		rcumodecommand->control().setEnable(true);
-	      }
-              break;
-	    }
+			case 'y': // --rcudelay
+				controlopt = strtoul(optarg, 0, 0);
+				if (controlopt > 127) {
+					logMessage(cerr,"Error: --rcudelay value should be <= 127");
+					delete command;
+					return 0;
+				}
+				rcumodecommand->control().setDelay((uint8)controlopt);
+			break;
 
-	  }
-	  break;
-
-	case 'g':	// --wg
-	  {
-	    if (command)
-	      delete command;
-	    WGCommand* wgcommand = new WGCommand(m_server);
-	    command = wgcommand;
-
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		wgcommand->setMode(false);
-		double frequency = atof(optarg);
-		if ( frequency < 0 ) {
-		    logMessage(cerr,"Error: option '--wg' parameter must be > 0");
-		    delete command;
-		    return 0;
-		  }
-		wgcommand->setFrequency(frequency, g_sample_frequency);
-	      }
-	  }
-	  break;
-
-	case 'G':	// --wgmode
-	  {
-	    if (optarg) {
-	      int mode = atoi(optarg);
-	      if (mode != 0 && mode != 1 && mode != 3 && mode != 5) {
-		logMessage(cerr,"Error: option '--wgmode' parameter must be 0,1,3 or 5");
-		delete command;
-		return 0;
-	      }
-	      WGCommand*	wgcommand = dynamic_cast<WGCommand*>(command);
-	      wgcommand->setWaveMode(mode);
-	    }
-	  }
-	  break;
-
-	case 'P':	// --phase
-	  {
-	    if (optarg) {
-	      double phase = atof(optarg);
-	      if (phase < 0 || phase > (M_PI * 2.0)) {
-		logMessage(cerr,"Error: option '--phase' parameter must be between 0 and 2 pi");
-		delete command;
-		return 0;
-	      }
-	      WGCommand*	wgcommand = dynamic_cast<WGCommand*>(command);
-	      wgcommand->setPhase((uint8)((phase / (2 * M_PI)) * (1 << 8)));
-	    }
-	  }
-	  break;
-
-	case 'A':  // --amplitude
-	  {
-	    if (optarg) {
-	      double amplitude = atof(optarg);
-	      if (amplitude > 2.0 || amplitude < 0.0) {
-		logMessage(cerr, "Error: option '--amplitude' paramter must be >= 0 and <= 1.0");
-		delete command;
-		return 0;
-	      }
-	      WGCommand *wgcommand = dynamic_cast<WGCommand*>(command);
-	      wgcommand->setAmplitude(amplitude);
-	    }
-	  }
-	  break;
+			case 'E': // --rcuenable
+				if (optarg && !strncmp(optarg, "0", 1)) {
+					rcumodecommand->control().setEnable(false);
+				} else {
+					rcumodecommand->control().setEnable(true);
+				}
+			break;
+			} // switch
 
-	case 'q' :	// --status
-	  {
-	    if (command)
-	      delete command;
-	    StatusCommand* statuscommand = new StatusCommand(m_server);
-	    command = statuscommand;
+		}
+		break;
 
-	    command->set_ndevices(m_nrspboards);
-	  }
-	  break;
-
-	case 'Q': // --tdstatus
-	  {
-	    if (command) delete command;
-	    TDStatusCommand* tdstatuscommand = new TDStatusCommand(m_server);
-	    command = tdstatuscommand;
-	    command->set_ndevices(m_nrspboards);
-	  }
-	  break;
-
-	case 't':	// --statistics
-	  {
-	    if (command)
-	      delete command;
-	    StatisticsCommand* statscommand = new StatisticsCommand(m_server);
-	    command = statscommand;
-
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		if (!strcmp(optarg, "subband")) {
-		  statscommand->setType(Statistics::SUBBAND_POWER);
-		} else if (!strcmp(optarg, "beamlet")) {
-		  command->set_ndevices(m_nrspboards * MEPHeader::N_POL);
-		  statscommand->setType(Statistics::BEAMLET_POWER);
-		} else {
-		  logMessage(cerr, formatString("Error: invalid statistics type %s", optarg));
-		  exit(EXIT_FAILURE);
+		case 'g':	// --wg
+		{
+			if (command)
+				delete command;
+			WGCommand* wgcommand = new WGCommand(m_server);
+			command = wgcommand;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				wgcommand->setMode(false);
+				double frequency = atof(optarg);
+				if ( frequency < 0 ) {
+					logMessage(cerr,"Error: option '--wg' parameter must be > 0");
+					delete command;
+					return 0;
+				}
+				wgcommand->setFrequency(frequency, g_sample_frequency);
+			}
 		}
-	      }
-	  }
-	  break;
-	case 'B':
-	  {
-	    xcangle = true;
-	  }
-	  break;
-
-	case 'x':	// -- xcstatistics
-	  {
-	    if (command)
-	      delete command;
-	    XCStatisticsCommand* xcstatscommand = new XCStatisticsCommand(m_server);
-	    xcstatscommand->setAngle(xcangle);
-	    command = xcstatscommand;
-	    command->set_ndevices(m_nrspboards);
-	  }
-	  break;
+		break;
 
-	case 'z':	// -- xcsubbands
-	  {
-	    if (command)
-	      delete command;
-	    SubbandsCommand* subbandscommand = new SubbandsCommand(m_server);
-	    subbandscommand->setType(SubbandSelection::XLET);
-	    command = subbandscommand;
+		case 'G':	// --wgmode
+		{
+			if (optarg) {
+				int mode = atoi(optarg);
+				if (mode != 0 && mode != 1 && mode != 3 && mode != 5) {
+					logMessage(cerr,"Error: option '--wgmode' parameter must be 0,1,3 or 5");
+					delete command;
+					return 0;
+				}
+				WGCommand*	wgcommand = dynamic_cast<WGCommand*>(command);
+				wgcommand->setWaveMode(mode);
+			}
+		}
+		break;
 
-	    command->set_ndevices(m_nrcus);
+		case 'P':	// --phase
+		{
+			if (optarg) {
+				double phase = atof(optarg);
+				if (phase < 0 || phase > (M_PI * 2.0)) {
+					logMessage(cerr,"Error: option '--phase' parameter must be between 0 and 2 pi");
+					delete command;
+					return 0;
+				}
+				WGCommand*	wgcommand = dynamic_cast<WGCommand*>(command);
+				wgcommand->setPhase((uint8)((phase / (2 * M_PI)) * (1 << 8)));
+			}
+		}
+		break;
 
-	    if (optarg) {
-		subbandscommand->setMode(false);
+		case 'A':  // --amplitude
+		{
+			if (optarg) {
+				double amplitude = atof(optarg);
+				if (amplitude > 2.0 || amplitude < 0.0) {
+					logMessage(cerr, "Error: option '--amplitude' paramter must be >= 0 and <= 1.0");
+					delete command;
+					return 0;
+				}
+				WGCommand *wgcommand = dynamic_cast<WGCommand*>(command);
+				wgcommand->setAmplitude(amplitude);
+			}
+		}
+		break;
 
-		int subband = atoi(optarg);
+		case 'q' :	// --status
+		{
+			if (command)
+				delete command;
+			StatusCommand* statuscommand = new StatusCommand(m_server);
+			command = statuscommand;
 
-		if (subband < 0 || subband >= MEPHeader::N_SUBBANDS) {
-		    logMessage(cerr,formatString("Error: argument to --xcsubband out of range, value must be >= 0 and < %d",MEPHeader::N_SUBBANDS));
-		    exit(EXIT_FAILURE);
+			command->set_ndevices(m_nrspboards);
 		}
+		break;
 
-		list<int> subbandlist;
-		for (int rcu = 0; rcu < m_nrcus / MEPHeader::N_POL; rcu++) {
-		    subbandlist.push_back(subband);
+		case 'Q': // --tdstatus
+		{
+			if (command) 
+				delete command;
+			TDStatusCommand* tdstatuscommand = new TDStatusCommand(m_server);
+			command = tdstatuscommand;
+			command->set_ndevices(m_nrspboards);
 		}
-		subbandscommand->setSubbandList(subbandlist);
-	      }
-	  }
-	  break;
-
-	case 'c':	// --clock
-	  {
-	    if (command)
-	      delete command;
-	    ClockCommand* clockcommand = new ClockCommand(m_server);
-	    command = clockcommand;
-
-	    command->set_ndevices(m_nrspboards);
-
-	    if (optarg) {
-		clockcommand->setMode(false);
-		double clock = atof(optarg);
-		if ( 0 != (uint32)clock && 160 != (uint32)clock && 200 != (uint32)clock)
-		  {
-		    logMessage(cerr,"Error: option '--clocks' parameter must be 0 (off), 160 (MHz) or 200 (MHz)");
-		    delete command;
-		    return 0;
-		  }
-		clockcommand->setClock((uint32)clock);
+		break;
 
-	      }
-	  }
-	  break;
-
-	case 'C': // --rspclear
-	  {
-	    if (command)
-	      delete command;
-	    RSUCommand* rsucommand = new RSUCommand(m_server);
-	    command = rsucommand;
-	    command->set_ndevices(m_nrspboards);
-
-	    rsucommand->setMode(false);	// is a SET command
-	    rsucommand->control().setClear(true);
-	  }
-	  break;
+		case 't':	// --statistics
+		{
+			if (command)
+				delete command;
+			StatisticsCommand* statscommand = new StatisticsCommand(m_server);
+			command = statscommand;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				if (!strcmp(optarg, "subband")) {
+					statscommand->setType(Statistics::SUBBAND_POWER);
+				} else if (!strcmp(optarg, "beamlet")) {
+					command->set_ndevices(m_nrspboards * MEPHeader::N_POL);
+					statscommand->setType(Statistics::BEAMLET_POWER);
+				} else {
+					logMessage(cerr, formatString("Error: invalid statistics type %s", optarg));
+					exit(EXIT_FAILURE);
+				}
+			}
+		}
+		break;
 
-	case 'S': // --regstate
-	  {
-	    if (command) delete command;
-	    RegisterStateCommand* regstatecommand = new RegisterStateCommand(m_server);
-	    command = regstatecommand;
-	  }
-	  break;
-
-	case 'v':	// --version
-	  {
-	    if (command)
-	      delete command;
-	    VersionCommand* versioncommand = new VersionCommand(m_server);
-	    command = versioncommand;
-	    command->set_ndevices(m_nrspboards);
-	  }
-	  break;
+		case 'B':
+		{
+			xcangle = true;
+		}
+		break;
 
-	case 'H':       // --hbadelays
-	  {
-	    if (!hbacommand) {
-	      if (command) delete command;
-	      hbacommand = new HBACommand(m_server);
-	    }
+		case 'x':	// -- xcstatistics
+		{
+			if (command)
+				delete command;
+			XCStatisticsCommand* xcstatscommand = new XCStatisticsCommand(m_server);
+			xcstatscommand->setAngle(xcangle);
+			command = xcstatscommand;
+			command->set_ndevices(m_nrspboards);
+		}
+		break;
 
-	    command = hbacommand;
-	    command->set_ndevices(m_nrcus);
+		case 'z':	// -- xcsubbands
+		{
+			if (command)
+				delete command;
+			SubbandsCommand* subbandscommand = new SubbandsCommand(m_server);
+			subbandscommand->setType(SubbandSelection::XLET);
+			command = subbandscommand;
 
-	    if (optarg) {
-	      hbacommand->setMode(false); // set the HBA delays
+			command->set_ndevices(m_nrcus);
 
-	      hbacommand->setDelayList(strtolist(optarg, (uint8)-1));
-	    }
-	  }
-	  break;
-
-	case 'T': // --tbbmode
-	  {
-	    if (command) delete command;
-	    TBBCommand* tbbcommand = new TBBCommand(m_server);
-	    command = tbbcommand;
-
-	    command->set_ndevices(m_nrcus);
-
-	    if (optarg) {
-		tbbcommand->setMode(false);
-		if (!strcmp(optarg, "transient")) {
-		  tbbcommand->setType(TBBCommand::TRANSIENT);
-		} else if (!strncmp(optarg, "subbands", strlen("subbands"))) {
-		  tbbcommand->setType(TBBCommand::SUBBANDS);
-
-		  char* liststring = strchr(optarg, ',');
-		  liststring++; // skip the ,
-		  if (liststring && *liststring) {
-		    list<int> subbandlist = strtolist(liststring, MEPHeader::N_SUBBANDS);
-		    if (subbandlist.empty()) {
-		      logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option");
-		      exit(EXIT_FAILURE);
-		    }
-		    tbbcommand->setSubbandSet(subbandlist);
-		  } else {
-		    logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option");
-		  }
-		} else {
-		  logMessage(cerr, formatString("Error: invalid statistics type %s", optarg));
-		  exit(EXIT_FAILURE);
+			if (optarg) {
+				subbandscommand->setMode(false);
+
+				int subband = atoi(optarg);
+
+				if (subband < 0 || subband >= MEPHeader::N_SUBBANDS) {
+					logMessage(cerr,formatString("Error: argument to --xcsubband out of range, value must be >= 0 and < %d",MEPHeader::N_SUBBANDS));
+					exit(EXIT_FAILURE);
+				}
+
+				list<int> subbandlist;
+				for (int rcu = 0; rcu < m_nrcus / MEPHeader::N_POL; rcu++) {
+					subbandlist.push_back(subband);
+				}
+				subbandscommand->setSubbandList(subbandlist);
+			}
 		}
-	      }
-	  }
-	  break;
+		break;
+
+		case 'c':	// --clock
+		{
+			if (command)
+				delete command;
+			ClockCommand* clockcommand = new ClockCommand(m_server);
+			command = clockcommand;
+
+			command->set_ndevices(m_nrspboards);
+
+			if (optarg) {
+				clockcommand->setMode(false);
+				double clock = atof(optarg);
+				if ( 0 != (uint32)clock && 160 != (uint32)clock && 200 != (uint32)clock) {
+					logMessage(cerr,"Error: option '--clocks' parameter must be 0 (off), 160 (MHz) or 200 (MHz)");
+					delete command;
+					return 0;
+				}
+				clockcommand->setClock((uint32)clock);
+			}
+		}
+		break;
+
+		case 'C': // --rspclear
+		{
+			if (command)
+				delete command;
+			RSUCommand* rsucommand = new RSUCommand(m_server);
+			command = rsucommand;
+			command->set_ndevices(m_nrspboards);
+
+			rsucommand->setMode(false);	// is a SET command
+			rsucommand->control().setClear(true);
+		}
+		break;
 
-	case 'I': // --spectral Inversion
-	  {
-	    if (command)
-	      delete command;
-	    SICommand* specInvCmd = new SICommand(m_server);
-	    command = specInvCmd;
+		case 'S': // --regstate
+		{
+			if (command) 
+				delete command;
+			RegisterStateCommand* regstatecommand = new RegisterStateCommand(m_server);
+			command = regstatecommand;
+		}
+		break;
 
-	    command->set_ndevices(m_nrcus);
+		case 'v':	// --version
+		{
+			if (command)
+				delete command;
+			VersionCommand* versioncommand = new VersionCommand(m_server);
+			command = versioncommand;
+			command->set_ndevices(m_nrspboards);
+		}
+		break;
 
-	    if (optarg) {
-		specInvCmd->setMode(false);
-		specInvCmd->setSI(strncmp(optarg, "0", 1));
-	    }
-	  }
-	  break;
+		case 'R':       // --realdelays
+			realDelays = true;
+			// no break!!!
+		case 'H':       // --hbadelays
+		{
+			if (!hbacommand) {
+				if (command) 
+					delete command;
+				hbacommand = new HBACommand(m_server);
+			}
 
-	case 'h':	// --help
-	  usage();
-	  break;
+			command = hbacommand;
+			command->set_ndevices(m_nrcus);
 
-#ifdef ENABLE_RSPFE
-	case 'f':	// --feport
-	  if (optarg) {
-	      if (!command || 0 == command->get_ndevices()) {
-		  logMessage(cerr,"Error: 'command' argument should come before --feport argument");
-		  exit(EXIT_FAILURE);
+			if (optarg) {
+				hbacommand->setMode(false); // set the HBA delays
+				hbacommand->setDelayList(strtolist(optarg, (uint8)-1));
+			}
 		}
-	      FECommand* feCommand = dynamic_cast<FECommand*>(command);
-	      if (feCommand == 0) {
-		  logMessage(cerr,"Error: 'feport' argument can not be used in conjunction with the specified command");
-		  exit(EXIT_FAILURE);
+		break;
+
+		case 'T': // --tbbmode
+		{
+			if (command) 
+				delete command;
+			TBBCommand* tbbcommand = new TBBCommand(m_server);
+			command = tbbcommand;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				tbbcommand->setMode(false);
+				if (!strcmp(optarg, "transient")) {
+					tbbcommand->setType(TBBCommand::TRANSIENT);
+				} else if (!strncmp(optarg, "subbands", strlen("subbands"))) {
+					tbbcommand->setType(TBBCommand::SUBBANDS);
+
+					char* liststring = strchr(optarg, ',');
+					liststring++; // skip the ,
+					if (liststring && *liststring) {
+						list<int> subbandlist = strtolist(liststring, MEPHeader::N_SUBBANDS);
+						if (subbandlist.empty()) {
+							logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option");
+							exit(EXIT_FAILURE);
+						}
+						tbbcommand->setSubbandSet(subbandlist);
+					} else {
+						logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option");
+					}
+				} else {
+					logMessage(cerr, formatString("Error: invalid statistics type %s", optarg));
+					exit(EXIT_FAILURE);
+				}
+			}
 		}
-	      feCommand->setFrontEnd(optarg);
-	    }
-	  else {
-	      logMessage(cerr,"Error: option '--feport' requires an argument");
-	    }
-	  break;
+		break;
+
+		case 'I': // --spectral Inversion
+		{
+			if (command)
+				delete command;
+			SICommand* specInvCmd = new SICommand(m_server);
+			command = specInvCmd;
+
+			command->set_ndevices(m_nrcus);
+
+			if (optarg) {
+				specInvCmd->setMode(false);
+				specInvCmd->setSI(strncmp(optarg, "0", 1));
+			}
+		}
+		break;
+
+		case 'h':	// --help
+			usage();
+		break;
+
+#ifdef ENABLE_RSPFE
+		case 'f':	// --feport
+			if (optarg) {
+				if (!command || 0 == command->get_ndevices()) {
+					logMessage(cerr,"Error: 'command' argument should come before --feport argument");
+					exit(EXIT_FAILURE);
+				}
+				FECommand* feCommand = dynamic_cast<FECommand*>(command);
+				if (feCommand == 0) {
+					logMessage(cerr,"Error: 'feport' argument can not be used in conjunction with the specified command");
+					exit(EXIT_FAILURE);
+				}
+				feCommand->setFrontEnd(optarg);
+			}
+			else {
+				logMessage(cerr,"Error: option '--feport' requires an argument");
+			}
+		break;
 #endif
 
-	case 'd':	// --duration
-	  if (optarg) {
-	      if (!command || 0 == command->get_ndevices()) {
-		  logMessage(cerr,"Error: 'command' argument should come before --duration argument");
-		  exit(EXIT_FAILURE);
-	      }
-	      StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command);
-	      if (statisticsBaseCommand == 0) {
-		  logMessage(cerr,"Error: 'duration' argument can not be used in conjunction with the specified command");
-		  exit(EXIT_FAILURE);
-	      }
-	      statisticsBaseCommand->setDuration(atoi(optarg));
-	  }
-	  else {
-	      logMessage(cerr,"Error: option '--duration' requires an argument");
-	  }
-	  break;
+		case 'd':	// --duration
+			if (optarg) {
+				if (!command || 0 == command->get_ndevices()) {
+					logMessage(cerr,"Error: 'command' argument should come before --duration argument");
+					exit(EXIT_FAILURE);
+				}
+				StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command);
+				if (statisticsBaseCommand == 0) {
+					logMessage(cerr,"Error: 'duration' argument can not be used in conjunction with the specified command");
+					exit(EXIT_FAILURE);
+				}
+				statisticsBaseCommand->setDuration(atoi(optarg));
+			}
+			else {
+				logMessage(cerr,"Error: option '--duration' requires an argument");
+			}
+		break;
 
-	case 'i':	// -- integration
-	  if (optarg) {
-	      if (!command || 0 == command->get_ndevices()) {
-		  logMessage(cerr,"Error: 'command' argument should come before --integration argument");
-		  exit(EXIT_FAILURE);
-	      }
-	      StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command);
-	      if (statisticsBaseCommand == 0) {
-		  logMessage(cerr,"Error: 'integration' argument can not be used in conjunction with the specified command");
-		  exit(EXIT_FAILURE);
-	      }
-	      statisticsBaseCommand->setIntegration(atoi(optarg));
-	  }
-	  else {
-	      logMessage(cerr,"Error: option '--integration' requires an argument");
-	  }
-	  break;
+		case 'i':	// -- integration
+			if (optarg) {
+				if (!command || 0 == command->get_ndevices()) {
+					logMessage(cerr,"Error: 'command' argument should come before --integration argument");
+					exit(EXIT_FAILURE);
+				}
+				StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command);
+				if (statisticsBaseCommand == 0) {
+					logMessage(cerr,"Error: 'integration' argument can not be used in conjunction with the specified command");
+					exit(EXIT_FAILURE);
+				}
+				statisticsBaseCommand->setIntegration(atoi(optarg));
+			}
+			else {
+				logMessage(cerr,"Error: option '--integration' requires an argument");
+			}
+		break;
 
 //	case 'I':	// -- instance
 //	  if (optarg) {
@@ -3038,38 +3077,38 @@ Command* RSPCtl::parse_options(int argc, char** argv)
 //	  }
 //	  break;
 
-	case 'D':	// -- directory
-	  if (optarg) {
-	      if (!command || 0 == command->get_ndevices()) {
-		  logMessage(cerr,"Error: 'command' argument should come before --directory argument");
-		  exit(EXIT_FAILURE);
-	      }
-	      StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command);
-	      if (statisticsBaseCommand == 0) {
-		  logMessage(cerr,"Error: 'directory' argument can not be used in conjunction with the specified command");
-		  exit(EXIT_FAILURE);
-	      }
-	      statisticsBaseCommand->setDirectory(optarg);
-	  }
-	  else {
-	      logMessage(cerr,"Error: option '--directory' requires an argument");
-	  }
-	  break;
+		case 'D':	// -- directory
+			if (optarg) {
+				if (!command || 0 == command->get_ndevices()) {
+					logMessage(cerr,"Error: 'command' argument should come before --directory argument");
+					exit(EXIT_FAILURE);
+				}
+				StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command);
+				if (statisticsBaseCommand == 0) {
+					logMessage(cerr,"Error: 'directory' argument can not be used in conjunction with the specified command");
+					exit(EXIT_FAILURE);
+				}
+				statisticsBaseCommand->setDirectory(optarg);
+			}
+			else {
+				logMessage(cerr,"Error: option '--directory' requires an argument");
+			}
+		break;
 
-	case '?':
-	default:
-	  logMessage(cerr, "Error: invalid option");
-	  exit(EXIT_FAILURE);
-	  break;
-	}
+		case '?':
+		default:
+			logMessage(cerr, "Error: invalid option");
+			exit(EXIT_FAILURE);
+		break;
+		}
     }
 
-  if (command) {
-      command->setSelect(select);
-      command->setBeamlets(beamlets);
-  }
+	if (command) {
+		command->setSelect(select);
+		command->setBeamlets(beamlets);
+	}
 
-  return command;
+	return (command);
 }
 
 std::list<int> RSPCtl::strtolist(const char* str, int max)
@@ -3143,7 +3182,7 @@ void RSPCtl::logMessage(ostream& stream, const string& message)
 
 int main(int argc, char** argv)
 {
-  GCFTask::init(argc, argv);
+  GCFTask::init(argc, argv, "rspctl");
 
   LOG_INFO(formatString("Program %s has started", argv[0]));
 
diff --git a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
index eddde48b55f..80acb10d617 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
+++ b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
@@ -125,6 +125,8 @@ static const int FAILURE         = 0;
 // SETHBAACK			(timestamp,	status)
 // GETHBA				(timestamp,	rcumask,cache)
 // GETHBAACK			(timestamp,	status,	settings)
+// READHBA				(timestamp,	rcumask,cache)
+// READHBAACK			(timestamp,	status,	settings)
 // SUBHBA				(timestamp,	rcumask,period)
 // SUBHBAACK			(timestamp,	status,	handle)
 // UPDHBA				(timestamp,	status,	handle,	settings)
@@ -1423,6 +1425,43 @@ event = {
   };
 };
 
+event = {
+  signal = READHBA;
+  dir = IN;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "rcumask";
+    type = "bitset<MEPHeader::MAX_N_RCUS>";
+  };
+  param = {
+    name = "cache";
+    type = "uint8";
+  };
+};
+
+event = {
+  signal = READHBAACK;
+  dir = OUT;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "status";
+    type = "int16";
+  };
+  param = {
+    name = "settings";
+    type = "HBASettings";
+    userdefined;
+  };
+};
+
 event = {
   signal = SUBHBA;
   dir = IN;
diff --git a/MAC/MACIO/include/MACIO/MACServiceInfo.h b/MAC/MACIO/include/MACIO/MACServiceInfo.h
index 7f2c20aed8b..306451cce8e 100644
--- a/MAC/MACIO/include/MACIO/MACServiceInfo.h
+++ b/MAC/MACIO/include/MACIO/MACServiceInfo.h
@@ -42,7 +42,7 @@ namespace LOFAR {
 #define	MAC_SERVICEBROKER_PORT			24000
 
 // Define names for the services
-#define MAC_SVCMASK_RSPDRIVER			"RSPDriver%s:acceptor_v3"
+#define MAC_SVCMASK_RSPDRIVER			"RSPDriver%s:acceptor_v3.1"
 #define	MAC_SVCMASK_CALSERVER			"CalServer%s:acceptor_v2"
 #define MAC_SVCMASK_BEAMSERVER			"BeamServer%s:acceptor_v2"
 #define MAC_SVCMASK_TBBDRIVER			"TBBDriver%s:acceptor"
-- 
GitLab