From cc89f207d7d71b329e5b65cac6e0532e7a15b776 Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Wed, 9 Jan 2013 09:17:09 +0000
Subject: [PATCH] Task #1418: Added UDP port code from Apertif.

---
 MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h       |  20 ++--
 MAC/GCF/TM/src/Port/GCF_RawPort.cc            |   5 +-
 MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc     |  57 +++------
 MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc        | 103 ++++++++++++----
 MAC/GCF/TM/src/PortImpl/GTM_ETHSocket.cc      |  78 ++++--------
 MAC/GCF/TM/src/PortImpl/GTM_File.cc           |   9 +-
 MAC/GCF/TM/src/PortImpl/GTM_FileHandler.cc    |  14 +--
 .../TM/src/PortImpl/GTM_TCPServerSocket.cc    |  72 ++++++-----
 MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.h |   3 +-
 MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc      | 113 ++++++++++++------
 MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.h       |  13 +-
 MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc |   1 +
 .../TM/src/ServiceBroker/ServiceBrokerTask.cc |  85 +++++++++----
 13 files changed, 340 insertions(+), 233 deletions(-)

diff --git a/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h b/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h
index 2440ac1af01..36c3fe5f19a 100644
--- a/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h
+++ b/MAC/GCF/TM/include/GCF/TM/GCF_TCPPort.h
@@ -52,10 +52,11 @@ class GCFTCPPort : public GCFRawPort
 public:// consturctors && destructors
     /// params see constructor of GCFPortInterface    
     GCFTCPPort (GCFTask& 		task,
-						 const string&	name,
-						 TPortType 		type,
-						 int 			protocol, 
-						 bool 			transportRawData = false);
+				const string&	name,
+				TPortType 		type,
+				int 			protocol, 
+				bool 			transportRawData = false,
+				bool			useUDP = false);
     
     /** default constructor 
      * GCFPortInterface params are:
@@ -75,7 +76,7 @@ public:// consturctors && destructors
                const string& name, 
                TPortType 	 type, 
                int 			 protocol, 
-               bool 		 transportRawData = false); 
+               bool 		 transportRawData = false);
 
     // open/close methods
     virtual bool open ();
@@ -83,8 +84,8 @@ public:// consturctors && destructors
       
     // send/recv functions
     virtual ssize_t send (GCFEvent& event);
-    virtual ssize_t recv (void* buf,
-                          size_t count);
+    virtual ssize_t send (void* buf, size_t count);		// for RAW ports
+    virtual ssize_t recv (void* buf, size_t count);
 
 	// Special auto-open mode that does the retries itself
 	// nrRetries		: -1 = infinite ; How often to retry the open when it fails.
@@ -106,6 +107,9 @@ public:// consturctors && destructors
     string getHostName();
     unsigned int getPortNumber();
 
+	// support of UDP
+	void useUDP(bool useIt) { itsUseUDP = useIt; }
+
 private:  
     /// copying is not allowed.
     GCFTCPPort (const GCFTCPPort&);
@@ -120,6 +124,7 @@ private:
 
 	void _handleConnect();
 	void _handleDisconnect();
+	GCFEvent::TResult _recvUDPevent();
     
 	// ----- Data Members -----
 protected: 
@@ -130,6 +135,7 @@ private:
     TPeerAddr				_addr;
     string					_host;
     unsigned int			_portNumber;
+	bool					itsUseUDP;
 	bool					itsFixedPortNr;
 	bool					itsAutoOpen;
 	unsigned int			itsAutoOpenTimer;
diff --git a/MAC/GCF/TM/src/Port/GCF_RawPort.cc b/MAC/GCF/TM/src/Port/GCF_RawPort.cc
index b9676238e9c..14ecd90bfa4 100644
--- a/MAC/GCF/TM/src/Port/GCF_RawPort.cc
+++ b/MAC/GCF/TM/src/Port/GCF_RawPort.cc
@@ -305,11 +305,8 @@ GCFEvent::TResult GCFRawPort::recvEvent()
 // Note:
 string GCFRawPort::getRealName() const
 {
-//	return (isSlave() ? _pMaster->getName() : _name);
-
 	GCFPort*	thePort = (isSlave() ? _pMaster : (GCFPort*)(this));
-	return (thePort->usesModernServiceName() ? 
-						thePort->makeServiceName() : thePort->getName());
+	return (thePort->usesModernServiceName() ? thePort->makeServiceName() : thePort->getName());
 }
 
   } // namespace TM
diff --git a/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc b/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc
index a5fcfcf88ec..458507c68c9 100644
--- a/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc
+++ b/MAC/GCF/TM/src/PortImpl/GCF_ETHRawPort.cc
@@ -74,98 +74,80 @@ bool GCFETHRawPort::close()
 
 bool GCFETHRawPort::open()
 {
-  if (isConnected())
-  {
+  if (isConnected()) {
     LOG_WARN("already connected");
    
     return false;
   }
-  else if (MSPP == getType())
-  {
+  else if (MSPP == getType()) {
     LOG_ERROR(formatString ( 
         "ETH raw ports can not act as a MSPP (%s).",
         getRealName().c_str()));
     return false;
   }
   // check for ifname
-  if (_ifname == "")
-  {    
-    try 
-    {
+  if (_ifname == "") {    
+    try {
       string ifNameParam = formatString(
           PARAM_ETH_IFNAME,
           getTask()->getName().c_str(),
           getRealName().c_str());
       _ifname += globalParameterSet()->getString(ifNameParam);      
     }
-    catch (...)
-    {
+    catch (...) {
       LOG_ERROR("no interface name specified");
       return false;
     }
   }
 
-  if (_destMacStr == "")
-  {    
-    try 
-    {
+  if (_destMacStr == "") {    
+    try {
       string destMacParam = formatString(
           PARAM_ETH_MACADDR,
           getTask()->getName().c_str(),
           getRealName().c_str());
       _destMacStr += globalParameterSet()->getString(destMacParam);      
     }
-    catch (...)
-    {
+    catch (...) {
       LOG_ERROR("no destination mac adres is specified");
       return false;
     }
   }
 
-  if (_ethertype == 0x0000)
-  {
-    try 
-    {
+  if (_ethertype == 0x0000) {
+    try {
       string ethertypeParam = formatString(
           PARAM_ETH_ETHERTYPE,
           getTask()->getName().c_str(),
           getRealName().c_str());
       _ethertype += globalParameterSet()->getInt32(ethertypeParam);      
     }
-    catch (...)
-    {
+    catch (...) {
       // is optional so no problem.
     }
   }
-  if (!_pSocket)
-  {
-    if (isSlave())
-    {
+  if (!_pSocket) {
+    if (isSlave()) {
       LOG_ERROR(formatString (
   			  "Port %s is not initialised.",
   			  getRealName().c_str()));
       return false;
     }
-    else    
-    {
+    else    {
       _pSocket = new GTMETHSocket(*this);
     }
   } 
    
-  if (_pSocket->open(_ifname.c_str(), _destMacStr.c_str(), _ethertype) < 0)
-  {    
-    if (SAP == getType())
-    {
+  if (_pSocket->open(_ifname.c_str(), _destMacStr.c_str(), _ethertype) < 0) {    
+    if (SAP == getType()) {
       setState(S_DISCONNECTING);
       schedule_disconnected();
     }
-    else
-    {
+    else {
       return false;
     }
   }
-  else
-  { 
+  else { 
     setState(S_CONNECTING);
     schedule_connected();
   }
@@ -178,8 +160,7 @@ ssize_t GCFETHRawPort::send(GCFEvent& e)
 
   ASSERT(_pSocket);
 
-  if (!isConnected()) 
-  {
+  if (!isConnected()) {
     LOG_ERROR(formatString (
         "Port '%s' on task '%s' not connected! Event not sent!",
         getRealName().c_str(),
diff --git a/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc b/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc
index d2cbc5f33dd..17123057310 100644
--- a/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc
+++ b/MAC/GCF/TM/src/PortImpl/GCF_TCPPort.cc
@@ -35,6 +35,8 @@
 #include "GTM_TCPServerSocket.h"
 #include <errno.h>
 
+const uint UDP_BUFFER_SIZE = 1600;
+
 namespace LOFAR {
   namespace GCF {
     using namespace SB;
@@ -48,13 +50,15 @@ GCFTCPPort::GCFTCPPort(GCFTask& 	 task,
                        const string& name, 
                        TPortType 	 type, 
                        int 			 protocol, 
-                       bool 		 transportRawData) 
+                       bool 		 transportRawData,
+					   bool			 useUDP) 
   : GCFRawPort(task, name, type, protocol, transportRawData),
     _pSocket		  (0),
     _addrIsSet		  (false),
 	_addr			  (),
 	_host			  (myHostname(false)),
     _portNumber		  (0),
+	itsUseUDP		  (useUDP),
 	itsFixedPortNr	  (false),
 	itsAutoOpen		  (false),
 	itsAutoOpenTimer  (0),
@@ -65,10 +69,10 @@ GCFTCPPort::GCFTCPPort(GCFTask& 	 task,
     _broker			  (0)
 {
 	if (SPP == getType() || MSPP == getType()) {
-		_pSocket = new GTMTCPServerSocket(*this, (MSPP == type));
+		_pSocket = new GTMTCPServerSocket(*this, (MSPP == type), itsUseUDP);
 	}
 	else if (SAP == getType()) {
-		_pSocket = new GTMTCPSocket(*this);
+		_pSocket = new GTMTCPSocket(*this, itsUseUDP);
 	}  
 }
 
@@ -82,6 +86,7 @@ GCFTCPPort::GCFTCPPort()
 	_addr			  (),
 	_host			  (myHostname(false)),
     _portNumber		  (0),
+	itsUseUDP		  (false),
 	itsFixedPortNr	  (false),
 	itsAutoOpen		  (false),
 	itsAutoOpenTimer  (0),
@@ -124,6 +129,7 @@ void GCFTCPPort::init(GCFTask& 		task,
     _portNumber 	= 0;
     _host       	= myHostname(false);
     _addrIsSet  	= false;
+	itsUseUDP		= false;
 	itsFixedPortNr	= false;
     if (_pSocket) {
 		delete _pSocket;
@@ -152,17 +158,20 @@ bool GCFTCPPort::open()
 
 	// allocate a TCP socket when not done before.
 	if (!_pSocket) {
+		LOG_DEBUG_STR("No socket yet during 'open', creating it");
 		if (isSlave()) {
 			LOG_ERROR(formatString ("Port %s not initialised.", makeServiceName().c_str()));
 			return (false);
 		}
 
 		if ((getType() == SPP) || (getType() == MSPP)) {
-			_pSocket = new GTMTCPServerSocket(*this, (MSPP == getType()));
+			_pSocket = new GTMTCPServerSocket(*this, (MSPP == getType()), itsUseUDP);
+			ASSERTSTR(_pSocket, "Could not create GTMTCPServerSocket for port " << getName());
 		}
 		else {
 			ASSERTSTR (SAP == getType(), "Unknown TPCsocket type " << getType());
-			_pSocket = new GTMTCPSocket(*this);
+			_pSocket = new GTMTCPSocket(*this, itsUseUDP);
+			ASSERTSTR(_pSocket, "Could not create GTMTCPSocket for port " << getName());
 			_pSocket->setBlocking(false);
 		}
 	}
@@ -328,6 +337,9 @@ void GCFTCPPort::_handleConnect()
 //
 GCFEvent::TResult	GCFTCPPort::dispatch(GCFEvent&	event)
 {
+	LOG_TRACE_FLOW("GCFTCPPort::dispatch");
+
+	// autoOpen timer event?
 	if (event.signal == F_TIMER) {
 		GCFTimerEvent	*TEptr = static_cast<GCFTimerEvent*>(&event);
 		if (TEptr->arg == &itsAutoOpenTimer) {	// Max auto open time reached?
@@ -351,9 +363,46 @@ GCFEvent::TResult	GCFTCPPort::dispatch(GCFEvent&	event)
 		}
 	}
 
+	// UDP specialty?
+	if (itsUseUDP && event.signal == F_DATAIN && !isTransportRawData()) {
+		return (_recvUDPevent());
+	}
+
+	// fallback to default dispatcher.
 	return(GCFRawPort::dispatch(event));	// call dispatch from parent (RawPort).
 }
 
+GCFEvent::TResult GCFTCPPort::_recvUDPevent()
+{   
+	LOG_TRACE_FLOW("GCFTCPPort::recvUDPevent()");
+
+	char        event_buf[UDP_BUFFER_SIZE];
+	GCFEvent*   newEvent = new GCFEvent;
+	ASSERTSTR(newEvent, "Could not allocate memory for a GCFEvent class");
+
+	// read the bytes from the socket (must be done in one time)
+	size_t nrBytes = _pSocket->recv(event_buf, UDP_BUFFER_SIZE);
+	ASSERTSTR(nrBytes >= GCFEvent::sizeSignal + GCFEvent::sizeLength, "UPD packet too small: " << nrBytes);
+
+	// copy some fields of the Event structure                  
+	memcpy(&newEvent->signal, event_buf,                        GCFEvent::sizeSignal);
+	memcpy(&newEvent->length, event_buf + GCFEvent::sizeSignal, GCFEvent::sizeLength);
+
+	// check if payload matches nr of bytes received.
+	ASSERTSTR(newEvent->length == nrBytes - GCFEvent::sizeSignal - GCFEvent::sizeLength,
+				"Length (" << newEvent->length << ") doesn't match number is received bytes(" <<
+				nrBytes - GCFEvent::sizeSignal - GCFEvent::sizeLength <<")");
+
+	// dispatch the event to the task
+	newEvent->_buffer = event_buf;  // attach buffer to event
+	if (_pTask->doEvent(*newEvent, *this) == GCFEvent::NEXT_STATE) {
+		LOG_TRACE_STAT_STR("GCFITCPort::dispatch:Task returned NEXT_STATE, queing " << eventName(*newEvent));
+		_pTask->queueTaskEvent(*newEvent, *this);
+	}
+	newEvent->_buffer = 0;
+	delete newEvent;
+	return (GCFEvent::HANDLED);
+}
 
 //
 // serviceRegistered(resultToReturn, portNr)
@@ -443,38 +492,38 @@ void GCFTCPPort::serviceGone()
 //
 ssize_t GCFTCPPort::send(GCFEvent& e)
 {
-	ssize_t written = 0;
-
 	ASSERT(_pSocket);
 
 	if (!isConnected()) {
-		LOG_ERROR(formatString (
-					"Port '%s' on task '%s' not connected! Event not sent!",
+		LOG_ERROR(formatString ("Port '%s' on task '%s' not connected! Event not sent!",
 					getRealName().c_str(), getTask()->getName().c_str()));
 		return 0;
 	}
 
-	if (MSPP == getType())   {
+	if (getType() == MSPP && !itsUseUDP) {
 		return 0; // no messages can be send by this type of port
 	}
 
-#if 0
-	unsigned int packSize;
-	void* buf = e.pack(packSize);
-#else
 	e.pack();
 	char*	buf      = e.packedBuffer();
 	uint	packSize = e.bufferSize();
-#endif
 
-	LOG_TRACE_STAT(formatString (
-						"Sending event '%s' for task '%s' on port '%s'",
-						eventName(e).c_str(), 
-						getTask()->getName().c_str(), 
-						getRealName().c_str()));
+	LOG_TRACE_STAT(formatString ("Sending event '%s' for task '%s' on port '%s'",
+					eventName(e).c_str(), getTask()->getName().c_str(), getRealName().c_str()));
 
-	if ((written = _pSocket->send(buf, packSize)) != (ssize_t) packSize) {  
-		LOG_ERROR_STR("Could only send " << written << " of " << packSize << " bytes");
+	return (send(buf, packSize));
+}
+
+//
+// send(buf, size) for RAW ports
+//
+ssize_t GCFTCPPort::send(void* buf, size_t  count)
+{
+	ASSERT(_pSocket);
+
+	ssize_t	written;
+	if ((written = _pSocket->send(buf, count)) != (ssize_t) count) {  
+		LOG_ERROR_STR("Could only send " << written << " of " << count << " bytes");
 		setState(S_DISCONNECTING);     
 		LOG_TRACE_COND("write: state = DISCONNECTING");
 		_handleDisconnect();
@@ -494,9 +543,8 @@ ssize_t GCFTCPPort::recv(void* buf, size_t count)
 	ASSERT(_pSocket);
 
 	if (!isConnected()) {
-		LOG_ERROR(formatString (
-					"Port '%s' on task '%s' not connected! Can't read device!",
-					getRealName().c_str(), getTask()->getName().c_str()));
+		LOG_ERROR(formatString ("Port '%s' on task '%s' not connected! Can't read device!",
+								getRealName().c_str(), getTask()->getName().c_str()));
 		return 0;
 	}
 
@@ -555,6 +603,7 @@ void GCFTCPPort::setAddr(const TPeerAddr& addr)
 	_addrIsSet = ((_addr.taskname != "") && (_addr.portname != ""));
 	_deviceNameMask = formatString("%s:%s", _addr.taskname.c_str(), 
 											_addr.portname.c_str());
+	LOG_DEBUG_STR("AddrIsSet:" << (_addrIsSet?"Y":"N"));
 }
 
 //
@@ -569,6 +618,10 @@ bool GCFTCPPort::accept(GCFTCPPort& port)
 		return (false);
 	}
 
+	if (itsUseUDP) {
+		return (false);
+	}
+
 	GTMTCPServerSocket* pProvider = (GTMTCPServerSocket*)_pSocket;
 	if (port._pSocket == 0) {
 		port._pSocket = new GTMTCPSocket(port);
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_ETHSocket.cc b/MAC/GCF/TM/src/PortImpl/GTM_ETHSocket.cc
index ffdddddba50..6f8942c7129 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_ETHSocket.cc
+++ b/MAC/GCF/TM/src/PortImpl/GTM_ETHSocket.cc
@@ -51,12 +51,9 @@
 #include <linux/filter.h>
 #endif
 
-namespace LOFAR 
-{
- namespace GCF 
- {
-  namespace TM 
-  {
+namespace LOFAR {
+ namespace GCF {
+  namespace TM {
 
 GTMETHSocket::GTMETHSocket(GCFETHRawPort& port) :
   GTMFile(port)
@@ -152,37 +149,25 @@ int GTMETHSocket::open(const char* ifname,
     
     // open the raw socket
     socketFD = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
-    if (socketFD < 0)
-    {
-      LOG_ERROR(LOFAR::formatString ( 
-    			"open(PF_PACKET): %s", 
-          strerror(errno)));
+    if (socketFD < 0) {
+      LOG_ERROR(LOFAR::formatString ( "open(PF_PACKET): %s", strerror(errno)));
     	return socketFD;
     }
 
     // make large send/recv buffers
     int val = 262144;
-    if (::setsockopt(socketFD, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) < 0) 
-    {
-      LOG_WARN(LOFAR::formatString (
-          "setsockopt(SO_RCVBUF): %s", 
-          strerror(errno)));	
+    if (::setsockopt(socketFD, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) < 0) {
+      LOG_WARN(LOFAR::formatString ( "setsockopt(SO_RCVBUF): %s", strerror(errno)));	
     }
-    if (::setsockopt(socketFD, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) < 0) 
-    {
-      LOG_WARN(LOFAR::formatString (
-          "setsockopt(SO_SNDBUF): %s", 
-          strerror(errno)));  	
+    if (::setsockopt(socketFD, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) < 0) {
+      LOG_WARN(LOFAR::formatString ( "setsockopt(SO_SNDBUF): %s", strerror(errno)));  	
     }
 
    // find MAC address for specified interface
     struct ifreq ifr;
     strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
-    if (::ioctl(socketFD, SIOCGIFHWADDR, &ifr) < 0)
-    {
-      LOG_FATAL(LOFAR::formatString ( 
-          "ioctl(SIOCGIFHWADDR): %s", 
-          strerror(errno)));
+    if (::ioctl(socketFD, SIOCGIFHWADDR, &ifr) < 0) {
+      LOG_FATAL(LOFAR::formatString ( "ioctl(SIOCGIFHWADDR): %s", strerror(errno)));
       ::close(socketFD);
       return -1;
     }
@@ -191,17 +176,13 @@ int GTMETHSocket::open(const char* ifname,
     unsigned int hx;
     char macPart[3];
     // print MAC addres for source
-    for (int i = 0; i < ETH_ALEN; i++)
-    {
+    for (int i = 0; i < ETH_ALEN; i++) {
       hx = ifr.ifr_hwaddr.sa_data[i] & 0xff;
       snprintf(macPart, sizeof macPart, "%02x", hx);
       macAddress += macPart;
       if (i < ETH_ALEN - 1) macAddress += ':';
     }
-    LOG_DEBUG(LOFAR::formatString ( 
-        "SRC (%s) HWADDR: %s", 
-        ifname, 
-        macAddress.c_str()));
+    LOG_DEBUG(LOFAR::formatString ( "SRC (%s) HWADDR: %s", ifname, macAddress.c_str()));
     
     // convert HWADDR string to sll_addr
     convertCcp2sllAddr(destMacStr, destMac);
@@ -212,10 +193,7 @@ int GTMETHSocket::open(const char* ifname,
     memcpy((char*)(&mac_filter_insn[3].k) + 2, destMac, sizeof(__u16));
     mac_filter_insn[3].k = htonl(mac_filter_insn[3].k);
     filter.filter = mac_filter_insn;
-    if (::setsockopt(socketFD,
-		   SOL_SOCKET, SO_ATTACH_FILTER,
-		   &filter, sizeof(struct sock_fprog)) < 0)
-    {
+    if (::setsockopt(socketFD, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(struct sock_fprog)) < 0) {
       LOG_ERROR("setsockopt(SO_ATTACH_FILTER) failed");
       ::close(socketFD);
       return -1;
@@ -223,16 +201,13 @@ int GTMETHSocket::open(const char* ifname,
   
     // print MAC address for destination
     macAddress = "";
-    for (int i = 0; i < ETH_ALEN; i++)
-    {
+    for (int i = 0; i < ETH_ALEN; i++) {
       hx = destMac[i] & 0xff;
       snprintf(macPart, sizeof macPart, "%02x", hx);
       macAddress += macPart;
       if (i < ETH_ALEN - 1) macAddress += ':';
     }
-    LOG_DEBUG(LOFAR::formatString ( 
-        "DEST HWADDR: %s", 
-        macAddress.c_str()));
+    LOG_DEBUG(LOFAR::formatString ( "DEST HWADDR: %s", macAddress.c_str()));
   
     // fill in packet header for sending messages
     struct ethhdr* hdr = (struct ethhdr*)_sendPacket;
@@ -242,10 +217,8 @@ int GTMETHSocket::open(const char* ifname,
   
     // get interface index number
     strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
-    if (ioctl(socketFD, SIOCGIFINDEX, &ifr) < 0)
-    {
-      LOG_FATAL(LOFAR::formatString ( 
-          "ioctl(SIOCGIFINDEX)"));
+    if (ioctl(socketFD, SIOCGIFINDEX, &ifr) < 0) {
+      LOG_FATAL(LOFAR::formatString ( "ioctl(SIOCGIFINDEX)"));
       ::close(socketFD);
       return -1;
     }
@@ -259,12 +232,8 @@ int GTMETHSocket::open(const char* ifname,
     _sockaddr.sll_protocol = htons(ETH_P_ALL);
     _sockaddr.sll_ifindex = ifindex;
     _sockaddr.sll_hatype = ARPHRD_ETHER;
-    if (::bind(socketFD, (struct sockaddr*)&_sockaddr,
-	     sizeof(struct sockaddr_ll)) < 0)
-    {
-        LOG_FATAL(LOFAR::formatString ( 
-            "GCFETHRawPort::open; bind : %s",
-            strerror(errno)));
+    if (::bind(socketFD, (struct sockaddr*)&_sockaddr, sizeof(struct sockaddr_ll)) < 0) {
+        LOG_FATAL(LOFAR::formatString ( "GCFETHRawPort::open; bind : %s", strerror(errno)));
         ::close(socketFD);
         return -1;
     }
@@ -276,8 +245,8 @@ int GTMETHSocket::open(const char* ifname,
     so.mr_alen = 0;
     memset(&so.mr_address, 0, sizeof(so.mr_address));
     if (::setsockopt(socketFD, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
-       (void*)&so, sizeof(struct packet_mreq)) < 0)
-    {
+       (void*)&so, sizeof(struct packet_mreq)) < 0) {
+		// TODO
     }
   
     //
@@ -313,8 +282,7 @@ void GTMETHSocket::convertCcp2sllAddr(const char* destMacStr,
   sscanf(destMacStr, "%x:%x:%x:%x:%x:%x",
    &hx[0], &hx[1], &hx[2], &hx[3], &hx[4], &hx[5]);
    
-  for (int i = 0; i < ETH_ALEN; i++)
-  {
+  for (int i = 0; i < ETH_ALEN; i++) {
       destMac[i] = (char)hx[i];
   }
 }
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_File.cc b/MAC/GCF/TM/src/PortImpl/GTM_File.cc
index 5e49950b516..a4366947118 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_File.cc
+++ b/MAC/GCF/TM/src/PortImpl/GTM_File.cc
@@ -53,10 +53,8 @@ GTMFile::GTMFile(GCFRawPort& port) :
 GTMFile::~GTMFile()
 {
 	close();
-
 	GTMFileHandler::release();
 	_pHandler = 0;
-
 	itsScheduler = 0;
 }
 
@@ -65,20 +63,17 @@ bool GTMFile::close()
 	bool result(true);
 
 	if (_fd > -1) { 
+		ASSERT(_pHandler);
 		_pHandler->deregisterFile(*this);
-
 		result = (::close(_fd) == 0);
-
 		if (!result) {
 			LOG_ERROR(formatString ( "::close, error: %s", strerror(errno)));
-
 			// there is nothing we can do at this point, since we cannot know
 			// whether the fd is still valid.
 		}
 
 		_fd = -1;
 	}
-
 	return result;
 }
 
@@ -129,7 +124,7 @@ void GTMFile::setBlocking(bool	blocking) const
 
 	int flags = fcntl(_fd, F_GETFL);
 
-    if (blocking) {
+	if (blocking) {
 		fcntl(_fd, F_SETFL, flags | O_NONBLOCK);
 	} else {
 		fcntl(_fd, F_SETFL, flags & ~O_NONBLOCK);
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_FileHandler.cc b/MAC/GCF/TM/src/PortImpl/GTM_FileHandler.cc
index 5f4ffcb9cd2..a4dce1f9eb8 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_FileHandler.cc
+++ b/MAC/GCF/TM/src/PortImpl/GTM_FileHandler.cc
@@ -92,21 +92,21 @@ void GTMFileHandler::workProc()
 	fd_set testFDs = _readFDs;
 	testFiles = _files;
 
-  // map keys are sorted low-to-high, so last key is highest
-  int maxfd = testFiles.empty() ? 0 : testFiles.rbegin()->first;
+	// map keys are sorted low-to-high, so last key is highest
+	int maxfd = testFiles.empty() ? 0 : testFiles.rbegin()->first;
 
-  // wait for any file to be readable, or for our timeout
+	// wait for any file to be readable, or for our timeout
 	result = ::select(maxfd + 1, &testFDs, (fd_set *) 0, (fd_set *) 0, &select_timeout);
 
 	if (result >= 0) {
-    for (TFiles::iterator i = testFiles.begin(); i != testFiles.end() && _running; ++i) {
-      int fd = i->first;
-      GTMFile *file = i->second;
+		for (TFiles::iterator i = testFiles.begin(); i != testFiles.end() && _running; ++i) {
+			int fd = i->first;
+			GTMFile *file = i->second;
 
 			if (FD_ISSET(fd, &testFDs)) {
 				file->doWork();
 			}
-    }
+		}
 	}
 }
 
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc b/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc
index 29d6d8ae0dd..ecec7ec8eea 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc
+++ b/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.cc
@@ -39,8 +39,8 @@ namespace LOFAR {
  namespace GCF {
   namespace TM {
     
-GTMTCPServerSocket::GTMTCPServerSocket(GCFTCPPort& port, bool isProvider) : 
-	GTMTCPSocket(port),
+GTMTCPServerSocket::GTMTCPServerSocket(GCFTCPPort& port, bool isProvider, bool useUDP) : 
+	GTMTCPSocket(port, useUDP),
 	_isProvider(isProvider),
 	_pDataSocket(0)
 {
@@ -53,6 +53,8 @@ GTMTCPServerSocket::~GTMTCPServerSocket()
 
 bool GTMTCPServerSocket::open(unsigned int portNumber)
 {
+	LOG_TRACE_COND_STR("open:fd=" << _fd << ", port=" << _port.getName());
+
 	if (_fd != -1) {
 		if (_pDataSocket != 0) {
 			_pDataSocket->close();
@@ -61,7 +63,7 @@ bool GTMTCPServerSocket::open(unsigned int portNumber)
 		return (false);
 	}
 
-	int socketFD = ::socket(AF_INET, SOCK_STREAM, 0);
+	int socketFD = ::socket(AF_INET, itsUseUDP ? SOCK_DGRAM : SOCK_STREAM, 0);
 	if (socketFD == -1) {
 		LOG_WARN(formatString ( "::socket, error: %s", strerror(errno)));
 		return (false);
@@ -69,7 +71,7 @@ bool GTMTCPServerSocket::open(unsigned int portNumber)
 	unsigned int val = 1;
 	struct linger lin = { 1,1 };
 
-	if (::setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, (const void*)&val, sizeof val) < 0) {
+	if (::setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, (const void*)&val, sizeof(val)) < 0) {
 		LOG_WARN(formatString (
 					"Error on setting socket options SO_REUSEADDR: %s",
 					strerror(errno)));
@@ -77,7 +79,7 @@ bool GTMTCPServerSocket::open(unsigned int portNumber)
 		return false;
 	}
 
-	if (::setsockopt(socketFD, SOL_SOCKET, SO_LINGER, (const void*)&lin, sizeof lin) < 0) {
+	if (::setsockopt(socketFD, SOL_SOCKET, SO_LINGER, (const void*)&lin, sizeof(lin)) < 0) {
 		LOG_WARN(formatString (
 					"Error on setting socket options SO_LINGER: %s",
 					strerror(errno)));
@@ -95,10 +97,12 @@ bool GTMTCPServerSocket::open(unsigned int portNumber)
 		return (false);
 	}
 
-	if (::listen(socketFD, 5) == -1) {    
-		LOG_WARN(formatString ( "::listen, error: %s", strerror(errno)));
-		::close(socketFD);
-		return (false);
+	if (!itsUseUDP) {
+		if (::listen(socketFD, 5) == -1) {    
+			LOG_WARN(formatString ( "::listen, error: %s", strerror(errno)));
+			::close(socketFD);
+			return (false);
+		}
 	}
 
     // set non-blocking
@@ -127,6 +131,12 @@ bool GTMTCPServerSocket::open(unsigned int portNumber)
 void GTMTCPServerSocket::doWork()
 {
 	LOG_TRACE_FLOW("GTMTCPServerSocket::doWork()");
+	if (itsUseUDP) {
+		LOG_TRACE_FLOW("doWork: socket is UDP, assuming data-in event");
+		GCFEvent    dataInEvent(F_DATAIN);
+		forwardEvent(dataInEvent);
+		return;
+	}
 
 	if (_isProvider) {
 		GCFEvent acceptReqEvent(F_ACCEPT_REQ);
@@ -139,7 +149,7 @@ void GTMTCPServerSocket::doWork()
 		_pDataSocket = new GTMTCPSocket(pPort);
 		ASSERT (_pDataSocket->getFD() < 0);
 
-    if (_accept(*_pDataSocket)) {
+		if (_accept(*_pDataSocket)) {
 			GCFEvent connectedEvent(F_CONNECTED);
 			forwardEvent(connectedEvent);
 		}
@@ -157,11 +167,11 @@ void GTMTCPServerSocket::doWork()
 //
 bool GTMTCPServerSocket::accept(GTMFile& newSocket)
 {
-	if (_isProvider && _pDataSocket == 0) {
-    return _accept(newSocket);
-	} else {
-    return false;
-  }
+	if (!itsUseUDP && _isProvider && _pDataSocket == 0) {
+		return (_accept(newSocket));
+	} 
+
+	return (false);
 }
 
 //
@@ -173,20 +183,20 @@ bool GTMTCPServerSocket::_accept(GTMFile& newSocket)
 {
 	bool result;
 
-  struct sockaddr_in clientAddress;
-  socklen_t clAddrLen = sizeof clientAddress;
-  int newSocketFD;
+	struct sockaddr_in clientAddress;
+	socklen_t clAddrLen = sizeof clientAddress;
+	int newSocketFD;
 
-  /* loop to handle transient errors */
-  int retries = MAX_ACCEPT_RETRIES;
-  while ((newSocketFD = ::accept(_fd, (struct sockaddr*) &clientAddress, &clAddrLen)) < 0
-    && (EINTR == errno || EWOULDBLOCK == errno || EAGAIN == errno) && --retries > 0) 
-    /*noop*/;
+	/* loop to handle transient errors */
+	int retries = MAX_ACCEPT_RETRIES;
+	while ((newSocketFD = ::accept(_fd, (struct sockaddr*) &clientAddress, &clAddrLen)) < 0
+		&& (EINTR == errno || EWOULDBLOCK == errno || EAGAIN == errno) && --retries > 0) 
+		/*noop*/;
 
-  result = (newSocket.setFD(newSocketFD) > 0);
-  if (!result) {
-    LOG_WARN(formatString ("::accept, error: %s", strerror(errno)));
-  }
+	result = (newSocket.setFD(newSocketFD) > 0);
+	if (!result) {
+		LOG_WARN(formatString ("::accept(%d), error:(%d)=%s", _fd, errno, strerror(errno)));
+	}
 
 	return result;
 }
@@ -209,6 +219,10 @@ bool GTMTCPServerSocket::close()
 
 ssize_t GTMTCPServerSocket::send(void* buf, size_t count)
 {
+	if (itsUseUDP) {
+		return GTMTCPSocket::send(buf, count);
+	}
+
 	if (!_isProvider && _pDataSocket != 0) {
 		return _pDataSocket->send(buf, count);
 	}
@@ -217,6 +231,10 @@ ssize_t GTMTCPServerSocket::send(void* buf, size_t count)
 
 ssize_t GTMTCPServerSocket::recv(void* buf, size_t count, bool  raw)
 {
+	if (itsUseUDP) {
+		return GTMTCPSocket::recv(buf, count, raw);
+	}
+
 	if (!_isProvider && _pDataSocket != 0) {
 		return _pDataSocket->recv(buf, count, raw);
 	}
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.h b/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.h
index d7b3dee0141..a0e053934e4 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.h
+++ b/MAC/GCF/TM/src/PortImpl/GTM_TCPServerSocket.h
@@ -42,7 +42,8 @@ class GTMTCPServerSocket : public GTMTCPSocket
 public: 
 	// constructors, destructors and default operators
     GTMTCPServerSocket (GCFTCPPort& port, 
-                        bool isProvider = false);
+                        bool 		isProvider = false,
+						bool		useUDP = false);
     virtual ~GTMTCPServerSocket ();
   
 	// GTMTCPServerSocket specific member methods
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc b/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc
index 7467994e223..4e267e3240c 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc
+++ b/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.cc
@@ -33,6 +33,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
+#include <sys/ioctl.h>
 #include <sys/select.h>
 #include <fcntl.h>
 #include <netdb.h>
@@ -43,12 +44,38 @@ namespace LOFAR {
  namespace GCF {
   namespace TM {
 
-GTMTCPSocket::GTMTCPSocket(GCFTCPPort& port) :
-  GTMFile(port),
-  _connecting(false)
+GTMTCPSocket::GTMTCPSocket(GCFTCPPort& port, bool useUDP) :
+  GTMFile      (port),
+  itsUseUDP    (useUDP),
+  itsConnecting(false)
 {
 }
 
+void GTMTCPSocket::doWork()
+{
+	LOG_TRACE_FLOW("GTMTCPSocket::doWork()");
+	unsigned long bytesRead = 0;
+
+	if (ioctl(_fd, FIONREAD, &bytesRead) > -1) {
+		if (bytesRead == 0 && !itsUseUDP) {             // We need the test on UDP :-(
+			GCFEvent discoEvent(F_DISCONNECTED);
+			itsScheduler->queueEvent(0, discoEvent, &_port);
+		}
+		else {
+			GCFEvent dataEvent(F_DATAIN);
+			itsScheduler->queueEvent(0, dataEvent, &_port);
+		}
+	}
+	else {
+		ASSERT(_port.getTask());
+		LOG_FATAL(LOFAR::formatString ("%s(%s): Error in 'ioctl' on socket fd %d: %s",
+					_port.getTask()->getName().c_str(),
+					_port.getName().c_str(),
+					_fd,
+					strerror(errno)));
+	}
+}
+
 //
 // send(buf, count)
 //
@@ -62,7 +89,13 @@ ssize_t GTMTCPSocket::send(void* buf, size_t count)
 	ssize_t countLeft(count);
 	ssize_t written(0);
 	do {
-		written = ::write(_fd, ((char*)buf) + (count - countLeft), countLeft);
+		if (itsUseUDP) {
+			written = sendto(_fd, ((char*)buf) + (count - countLeft), countLeft, 0,
+							(struct sockaddr*) &itsTCPaddr, sizeof(itsTCPaddr));
+		}
+		else {
+			written = ::write(_fd, ((char*)buf) + (count - countLeft), countLeft);
+		}
 		if (written == 0) {		// is it a disconnect?
 			return (0);
 		}
@@ -96,7 +129,12 @@ ssize_t GTMTCPSocket::recv(void* buf, size_t count, bool raw)
 
 	ssize_t countLeft(count);
 	ssize_t received(0);
+	socklen_t   addrLen = sizeof(itsTCPaddr);
 	do {
+		if (itsUseUDP) {
+			return (recvfrom(_fd, (char*)buf, count, 0, (struct sockaddr*) &itsTCPaddr, &addrLen));
+		}
+
 		received = ::read(_fd, ((char*)buf) + (count - countLeft), countLeft);
 		if (received == 0) {	// is it a disconnect?
 			return(0);
@@ -127,7 +165,7 @@ bool GTMTCPSocket::open(unsigned int /*portNumber*/)
 		return (true);
 	}
 
-	_fd = ::socket(AF_INET, SOCK_STREAM, 0);
+	_fd = ::socket(AF_INET, itsUseUDP ? SOCK_DGRAM : SOCK_STREAM, 0);
 	if (_fd < 0) {
 		LOG_WARN(formatString ( "::socket, error: %s", strerror(errno)));
 		close();
@@ -151,22 +189,21 @@ int GTMTCPSocket::connect(unsigned int portNumber, const string& host)
 	LOG_TRACE_COND_STR(_port.getName() << ":connect(" << portNumber << "," << host << "),fd=" << _fd);
 
 	// try to resolve hostaddress/name
-	struct sockaddr_in serverAddr;
 	struct hostent *hostinfo;
 	hostinfo = gethostbyname(host.c_str());
 	ASSERTSTR(hostinfo, _port.getName() << ":hostname " << host << " could not be resolved, error = " << errno);
 
 	// try to connect
-	serverAddr.sin_family = AF_INET;
-	serverAddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
-	serverAddr.sin_port = htons(portNumber);
+	itsTCPaddr.sin_family = AF_INET;
+	itsTCPaddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
+	itsTCPaddr.sin_port = htons(portNumber);
 	errno = 0;
 
-        if (!_connecting) {
+	if (!itsConnecting) {
 		// create a new connection
-		if ((::connect(_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr_in)) == 0)) {
+		if ((::connect(_fd, (struct sockaddr *)&itsTCPaddr, sizeof(struct sockaddr_in)) == 0)) {
 			// connect succesfull, register filedescriptor
-      setFD(_fd);
+			setFD(_fd);
 			return (1);
 		}
 
@@ -174,11 +211,11 @@ int GTMTCPSocket::connect(unsigned int portNumber, const string& host)
 		if (errno != EINPROGRESS) {
 			// serious error
 			LOG_WARN_STR(_port.getName() << ":connect(" << host << "," << portNumber << "), error: " << strerror(errno));
-                        close();
+			close();
 			return (-1);	
 		}
 
-		_connecting = true;
+		itsConnecting = true;
 
 	} else {
 		// poll an existing connection
@@ -192,7 +229,7 @@ int GTMTCPSocket::connect(unsigned int portNumber, const string& host)
 		switch(::select(_fd + 1, NULL, &fds, NULL, &timeout)) {
 			case 0:
 				// no data available
-	                        break;
+				break;
 
 			case -1:
 				// serious error
@@ -201,31 +238,31 @@ int GTMTCPSocket::connect(unsigned int portNumber, const string& host)
 				return (-1);	
 
 			default:
-                                // data available OR connection error
-                                int so_error;
-                                socklen_t slen = sizeof so_error;
-                                if (getsockopt(_fd, SOL_SOCKET, SO_ERROR, &so_error, &slen) < 0) {
-                                    // serious error
-                                    LOG_WARN_STR(_port.getName() << ":getsockopt(" << host << "," << portNumber << "), error: " << strerror(errno));
-                                    close();
-                                    return (-1);	
-                                }
-
-                                if (so_error == 0) {
-                                    // connect succesfull, register filedescriptor
-                                    setFD(_fd);
-                                    return 1;
-                                }
-
-                                // connection failure
-                                LOG_WARN_STR(_port.getName() << ":connect(" << host << "," << portNumber << "), error: " << strerror(errno));
-                                close();
-                                return (-1);	
-		}
-	}
+				// data available OR connection error
+				int so_error;
+				socklen_t slen = sizeof so_error;
+				if (getsockopt(_fd, SOL_SOCKET, SO_ERROR, &so_error, &slen) < 0) {
+					// serious error
+					LOG_WARN_STR(_port.getName() << ":getsockopt(" << host << "," << portNumber << "), error: " << strerror(errno));
+					close();
+					return (-1);	
+				}
+				
+				if (so_error == 0) {
+					// connect succesfull, register filedescriptor
+					setFD(_fd);
+					return 1;
+				}
+
+				// connection failure
+				LOG_WARN_STR(_port.getName() << ":connect(" << host << "," << portNumber << "), error: " << strerror(errno));
+				close();
+				return (-1);	
+		} // switch
+	} // case
 
 	LOG_DEBUG_STR(_port.getName() << ": still waiting for connection");
-	return(0);
+	return (0);
 } 
 
   } // namespace TM
diff --git a/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.h b/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.h
index fa354a0a9f2..7980bbc256f 100644
--- a/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.h
+++ b/MAC/GCF/TM/src/PortImpl/GTM_TCPSocket.h
@@ -25,6 +25,7 @@
 
 #include "GTM_File.h"
 #include <Common/lofar_string.h>
+#include <netinet/in.h>
 
 namespace LOFAR {
  namespace GCF {
@@ -42,7 +43,7 @@ class GTMTCPSocket : public GTMFile
 {
 public: 
 	// constructors, destructors and default operators
-    GTMTCPSocket (GCFTCPPort& port);
+    GTMTCPSocket (GCFTCPPort& port, bool useUDP = false);
   
 	// GTMTCPSocket specific member methods
     // open/connect methods
@@ -54,13 +55,21 @@ public:
     virtual ssize_t send (void* buf, size_t count);
     virtual ssize_t recv (void* buf, size_t count, bool raw = false);
 
+protected:
+	virtual void doWork();
+
+	// --- datamembers ---
+	bool		itsUseUDP;
+
 private:
     GTMTCPSocket ();
     /// Don't allow copying of the GTMTCPSocket object.
     GTMTCPSocket (const GTMTCPSocket&);
     GTMTCPSocket& operator= (const GTMTCPSocket&);
 
-	bool	_connecting;
+	// --- datamembers ---
+	struct sockaddr_in  itsTCPaddr;
+	bool				itsConnecting;
 
 };
 
diff --git a/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc b/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc
index b9ec143458c..04466c4e7dc 100644
--- a/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc
+++ b/MAC/GCF/TM/src/ServiceBroker/GTM_SBTCPPort.cc
@@ -68,6 +68,7 @@ bool GTMSBTCPPort::open()
 
 	if (!_pSocket) {
 		_pSocket = new GTMTCPSocket(*this);
+		ASSERTSTR(_pSocket, "Could not create GTMTCPSocket for SBtask");
 		_pSocket->setBlocking(false);
 	}
 
diff --git a/MAC/GCF/TM/src/ServiceBroker/ServiceBrokerTask.cc b/MAC/GCF/TM/src/ServiceBroker/ServiceBrokerTask.cc
index 5e46d47170b..8efb555fbbb 100644
--- a/MAC/GCF/TM/src/ServiceBroker/ServiceBrokerTask.cc
+++ b/MAC/GCF/TM/src/ServiceBroker/ServiceBrokerTask.cc
@@ -203,13 +203,16 @@ void ServiceBrokerTask::deletePort(GCFTCPPort& aPort)
 	// clean up all action that refer to this port
     actionList_t 		tmpActionList;    	// NOTE: 'erase' reorders the elements of a list!!!
 	tmpActionList.swap(itsActionList);
-
-	for (ALiter iter = tmpActionList.begin(); iter != tmpActionList.end(); ++iter) {
+	ALiter		end  = tmpActionList.end();
+	ALiter		iter = tmpActionList.begin();
+	while (iter != end) {
 		LOG_TRACE_COND_STR("deletePort checking: " << iter->print());
 		if (iter->pPort != &aPort) {			// copy others only
 			itsActionList.push_back(*iter);
 		}
+		iter++;
 	}
+	tmpActionList.clear();
 
 	// unregister service of this port if any
 	_deleteService(aPort);
@@ -300,12 +303,21 @@ unsigned short ServiceBrokerTask::_registerAction(Action action)
 //
 void ServiceBrokerTask::_reRegisterServices(GCFPortInterface*	brokerPort)
 {
-	for (SMiter iter = itsServiceMap.begin(); iter != itsServiceMap.end(); ++iter) {
+	// nothing to do?
+	if (itsServiceMap.empty()) {
+		return;
+	}
+
+	SMiter	end  = itsServiceMap.end();
+	SMiter	iter = itsServiceMap.begin();
+	while (iter != end) {
 		SBReregisterServiceEvent	request;
 		request.seqnr 	    = 0;
 		request.servicename = iter->second.servicename;
 		request.portnumber  = iter->second.portNr;
 		brokerPort->send(request);
+
+		iter++;
 	}
 }
 
@@ -314,18 +326,23 @@ void ServiceBrokerTask::_reRegisterServices(GCFPortInterface*	brokerPort)
 //
 void ServiceBrokerTask::_doActionList(const string&	hostname)
 {
+	// nothing to do?
+	if (itsActionList.empty()) {
+		return;
+	}
 	_printActionList();
 
 	// Note: while processing the list, the list grows. Therefore we use actionsLeft.
     actionList_t 		tmpActionList;    	// NOTE: 'erase' reorders the elements of a list!!!
-
 	tmpActionList.swap(itsActionList);
-
-	for (ALiter iter = tmpActionList.begin(); iter != tmpActionList.end(); ++iter) {
+	ALiter		end  = tmpActionList.end();
+	ALiter		iter = tmpActionList.begin();
+	while (iter != end) {
 		LOG_TRACE_COND_STR("doActionList checking: " << iter->print());
 		// only process the actions for this host
 		if (iter->hostname != hostname) {
 			itsActionList.push_back(*iter);		// restore in original list.
+			iter++;
 			continue;
 		}
 
@@ -344,7 +361,9 @@ void ServiceBrokerTask::_doActionList(const string&	hostname)
 			ASSERTSTR(false, "Unknown action in actionlist: " << iter->type
 						<< ":" << iter->servicename << "@" << iter->hostname);
 		}
+		iter++;
 	}
+	tmpActionList.clear();
 }
 
 //
@@ -352,15 +371,22 @@ void ServiceBrokerTask::_doActionList(const string&	hostname)
 //
 void ServiceBrokerTask::_lostBroker(const string& hostname)
 {
+	// nothing to do?
+	if (itsActionList.empty()) {
+		return;
+	}
+
 	// Note: while processing the list, the list grows. Therefore we use actionsLeft.
     actionList_t 		tmpActionList;    	// NOTE: 'erase' reorders the elements of a list!!!
 	tmpActionList.swap(itsActionList);
-
-	for (ALiter iter = tmpActionList.begin(); iter != tmpActionList.end(); ++iter) {
+	ALiter		end  = tmpActionList.end();
+	ALiter		iter = tmpActionList.begin();
+	while (iter != end) {
 		LOG_TRACE_COND_STR("_lostBroker checking: " << iter->print());
 		// only process the actions for this host
 		if (iter->hostname != hostname) {
 			itsActionList.push_back(*iter);		// restore in original list.
+			iter++;
 			continue;
 		}
 
@@ -390,7 +416,9 @@ void ServiceBrokerTask::_lostBroker(const string& hostname)
 			ASSERTSTR(false, "Unknown action in actionlist: " << iter->type
 						<< ":" << iter->servicename << "@" << iter->hostname);
 		}
+		iter++;
 	}
+	tmpActionList.clear();
 }
 
 //
@@ -421,14 +449,17 @@ ServiceBrokerTask::BMiter	ServiceBrokerTask::_getBroker(const string&	hostname)
 //
 ServiceBrokerTask::ALiter	ServiceBrokerTask::_findAction(uint16	seqnr)
 {
-	for (ALiter iter = itsActionList.begin(); iter != itsActionList.end(); ++iter) {
+	ALiter	end  = itsActionList.end();
+	ALiter	iter = itsActionList.begin();
+	while (iter != end) {
 		LOG_TRACE_COND_STR("_findAction checking: " << iter->print());
 		if (iter->seqnr == seqnr) {
 			return (iter);
 		}
-	}
 
-	return itsActionList.end();
+		iter++;
+	}
+	return (iter);
 }
 
 //
@@ -438,12 +469,13 @@ void ServiceBrokerTask::_reconnectBrokers()
 {
 	LOG_DEBUG("_reconnectBrokers()");
 
-	// keep a next pointer because we're erasing elements
-	for (BMiter iter = itsBrokerMap.begin(), iter_next = iter; iter != itsBrokerMap.end(); iter = iter_next) {
-		++iter_next;
+	BMiter	end  = itsBrokerMap.end();
+	BMiter	iter = itsBrokerMap.begin();
 
+	while (iter != end) {
 		// ready when broker is connected
 		if (iter->second.port->isConnected()) {
+			iter++;
 			continue;
 		}
 
@@ -451,19 +483,21 @@ void ServiceBrokerTask::_reconnectBrokers()
 		if (--(iter->second.nRetries) > 0) {
 			iter->second.port->open();			// will result in F_CONN or F_DISCONN
 			_checkActionList(iter->first);
+			iter++;
 		}
 		else {
 			LOG_ERROR_STR("ServiceBroker on host " << iter->first << " is unreachable!");
 			_lostBroker(iter->first);
-
+			BMiter	tmp = iter;
+			iter++;
 			// remove broker except when its the SB on my host and some services were registered there.
-			if (iter->first == myHostname(false) && !itsServiceMap.empty()) {
-				iter->second.nRetries = MAX_RECONNECT_RETRIES;	// keep trying.
-				iter->second.port->open();						// might result in F_CONN or F_DISCONN
+			if (tmp->first == myHostname(false) && !itsServiceMap.empty()) {
+				tmp->second.nRetries = MAX_RECONNECT_RETRIES;	// keep trying.
+				tmp->second.port->open();						// might result in F_CONN or F_DISCONN
 			}
 			else {
-				LOG_DEBUG_STR("Removing servicebroker for " << iter->first << " from brokermap");
-				itsBrokerMap.erase(iter);
+				LOG_DEBUG_STR("Removing servicebroker for " << tmp->first << " from brokermap");
+				itsBrokerMap.erase(tmp);
 			}
 		}
 	}
@@ -478,9 +512,11 @@ void ServiceBrokerTask::_printActionList()
 		return;
 	}
 
+	ALiter	end  = itsActionList.end();
+	ALiter	iter = itsActionList.begin();
 	string	typeName;
 	LOG_TRACE_FLOW_STR("ActionList at " << time(0));
-	for (ALiter iter = itsActionList.begin(); iter != itsActionList.end(); ++iter) {
+	while (iter != end) {
 		switch (iter->type) {
 		case SB_REGISTER_SERVICE:	typeName = "Register";		break;
 		case SB_UNREGISTER_SERVICE: typeName = "Unregister";	break;
@@ -490,6 +526,7 @@ void ServiceBrokerTask::_printActionList()
 
 		LOG_DEBUG_STR(typeName << " " << iter->servicename << "@" << iter->hostname << 
 						"(" << iter->timestamp << "(" << iter->seqnr << "))");
+		++iter;
 	}
 }
 
@@ -503,9 +540,11 @@ void ServiceBrokerTask::_checkActionList(const string&	hostname)
 
     actionList_t 		tmpActionList;    	// NOTE: 'erase' reorders the elements of a list!!!
 	tmpActionList.swap(itsActionList);
+	ALiter		end  = tmpActionList.end();
+	ALiter		iter = tmpActionList.begin();
 	time_t	currentTime = time(0);
 	// check for which actions we are late.
-	for (ALiter iter = tmpActionList.begin(); iter != tmpActionList.end(); ++iter) {
+	while (iter != end) {
 		LOG_TRACE_COND_STR("_checkActionList checking: " << iter->print());
 		bool	actionHandled(false);
 		if (iter->hostname == hostname) {
@@ -536,7 +575,9 @@ void ServiceBrokerTask::_checkActionList(const string&	hostname)
 		if (!actionHandled) {
 			itsActionList.push_back(*iter);	// keep non-expired action
 		}
+		iter++;
 	}
+	tmpActionList.clear();
 }
 
 //
-- 
GitLab