diff --git a/MAC/APL/PIC/TBBDriver/src/BoardCmdHandler.cc b/MAC/APL/PIC/TBBDriver/src/BoardCmdHandler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..32729b6e54dc947d80f206118a6fd664a76e059b
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/BoardCmdHandler.cc
@@ -0,0 +1,184 @@
+//#  BoardCmdHandler.cc: implementation of the BoardCmdHandler class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <APL/TBB_Protocol/TP_Protocol.ph>
+#include <APL/TBB_Protocol/TBB_Protocol.ph>
+
+#include "BoardCmdHandler.h"
+
+using namespace LOFAR;
+using namespace TBB;
+
+#define N_RETRIES 10
+
+BoardCmdHandler::BoardCmdHandler()
+  : GCFFsm((State)&BoardCmdHandler::tp_send_state),
+    m_retries(0),
+		m_nr_of_boards(12)
+{	
+}
+
+BoardCmdHandler::~BoardCmdHandler()
+{	
+}
+
+GCFEvent::TResult BoardCmdHandler::send_state(GCFEvent& event, GCFPortInterface& port)
+{
+  GCFEvent::TResult status = GCFEvent::HANDLED;
+			
+  switch (event.signal)
+	{
+  	case F_ENTRY: {
+			m_SendMask = 0;
+		}	break;			
+		
+		case TBB_ALLOC:
+		{
+			TBBAlloc alloc(e);
+			alloc.tbbmask ...
+			}	
+		case TBB_FREE:
+		{
+			TBBFree free(e);
+			free.kljlkjlkj
+					}
+		case TBB_RECORD: 
+		case TBB_STOP:
+		case TBB_TRIGCLR:
+		case TBB_READ:
+		case TBB_UDP:
+		case TBB_VERSION:
+		case TBB_SIZE:
+		case TBB_CLEAR:
+		case TBB_RESET:
+		case TBB_CONFIG:
+		{
+			if(Cmd.isValid(event)) // isValid returns true if event is a valid cmd
+			{
+				m_ClientEvent = event;
+				m_ClientPort = port;
+				m_SendMask = event.tbbmask;
+				m_TpEvent = Cmd.getTpEvent(m_ClientEvent);
+				sendToBoards();
+			}
+		} break;
+		
+		case TBB_ERASEF:
+		case TBB_READF:
+		case TBB_WRITEF:
+		case TBB_READW:
+		case TBB_WRITEW:
+		{
+			if(Cmd.isValid(event)) // isValid returns true if event is a valid cmd
+			{
+				m_ClientEvent = event;
+				m_ClientPort = port;
+				m_SendMask = getMask(event.boardid);
+				m_TpEvent = Cmd.getTpEvent(event);
+				sendToBoards();
+			}
+		} break;
+						
+		default: {
+				status = GCFEvent::NOT_HANDLED;
+    } break;
+	}
+	
+	// board_send_mask must be cleared if command tbb_sendack_state is done
+	if(m_SendMask)
+	{
+		// TODO Set time-out Timer
+		TRAN(BoardCmdHandler::waitack_state);
+	}
+	return status;
+}
+
+
+GCFEvent::TResult BoardCmdHandler::waitack_state(GCFEvent& event, GCFPortInterface& port)
+{
+  GCFEvent::TResult status = GCFEvent::HANDLED;
+	  
+	switch(event.signal)
+	{
+  	case F_ENTRY: {
+			m_RecvMask = 0;
+		}	break;
+		    
+		case F_TIMER: {
+			m_ClienPort.send(getTbbAckEvent());
+			TRAN(BoardCmdHandler::send_state);
+		}	break;
+		
+    case F_EXIT: {
+		} break;
+      
+    default: {
+			if(Cmd.isValid(event))
+			{
+				saveTpAckEvent(event,port);
+			}
+			else
+			{
+				status = GCFEvent::NOT_HANDLED;
+			}
+		}	break;
+	}
+	 
+	if(m_SendMask == m_RecvMask)
+	{
+		m_ClienPort.send(getTbbAckEvent());
+		TRAN(BoardCmdHandler::send_state);
+	}
+	return status;
+}
+
+bool SetCmd(Command cmd)
+{
+	m_cmd = cmd;
+}
+
+void BoardCmdHandler::sendToBoards(void)
+{
+	// send command to all the boards in the send-mask
+	for (int boardnr = 0;boardnr < nr_of_boards;boardnr++)
+	{
+		if(user_event.tbbmask & (1 << boardnr))
+		{
+			board_port[boardnr].send(m_TpEvent);
+		}
+	}
+}
+
+uint32 BoardCmdHandler::getMask(uint32 boardid)
+{
+	// send command to all the boards in the send-mask
+	for (int boardnr = 0;boardnr < m_nr_of_boards;boardnr++)
+	{
+		if(boardid == board_id[boardnr]))
+		{
+			return (1 << boardnr);
+		}
+	}
+}
+
diff --git a/MAC/APL/PIC/TBBDriver/src/BoardCmdHandler.h b/MAC/APL/PIC/TBBDriver/src/BoardCmdHandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..134695d27b8886f998a8eba0dcbe0ec84f4ba52d
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/BoardCmdHandler.h
@@ -0,0 +1,83 @@
+//#  -*- mode: c++ -*-
+//#
+//#  BoardCmdHandler.h: TBB Driver boardaction class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+/*
+	Ieder commando heeft zijn eigen BoardCmdHandler, alle Tbb borden worden vanuit een module aangesproken. 
+	Ieder commando spreekt dus 12 borden aan, de Tbb borden waar iets naar toe moet worden gestuurt, 
+	worden bepaald door het mask.
+*/
+
+#ifndef BOARDCMDHANDLER_H_
+#define BOARDCMDHANDLER_H_
+
+#include <GCF/TM/GCF_Control.h>
+
+#include <Command.h>
+
+namespace LOFAR {
+	namespace TBB {
+	
+		class BoardCmdHandler : public GCFFsm
+		{
+	
+			public:
+
+				// Constructors for a SyncAction object.
+				// Default direction is read.
+				TbbBoardCmdHandler(GCFPortInterface& board_port, int board_id, int n_indices);
+
+				// Destructor for SyncAction. */
+				~TbbBoardCmdHandler();
+
+				// The states of the statemachine.
+				GCFEvent::TResult send_state(GCFEvent& event, GCFPortInterface& port);
+				GCFEvent::TResult waitack_state(GCFEvent& event, GCFPortInterface& port);
+				
+
+				
+				
+
+
+			protected:
+
+			private:
+				void sendToBoards(void);
+				uint32 getMask(uint32 boardid);
+				
+			private:
+				Command						m_cmd;
+				int								nr_of_boards;
+				GCFPortInterface&	board_port[m_nr_of_boards];
+				GCFPortInterface& m_client_port;
+				GCFEvent&					m_client_event;
+				GCFEvent&					m_TpEvent;
+				int								board_id[m_nr_of_boards];
+				uint32						m_SendMask;  /// mask indicates the boards to communicate with
+				uint32						m-RecvMask;																			
+				int								board_retries;
+		};
+	};
+};
+
+#endif /* BOARDACTION_H_ */
diff --git a/MAC/APL/PIC/TBBDriver/src/Command.cc b/MAC/APL/PIC/TBBDriver/src/Command.cc
new file mode 100644
index 0000000000000000000000000000000000000000..06554d904b319c4c31d48dee7c3508e50a508c49
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/Command.cc
@@ -0,0 +1,38 @@
+//#  Command.cc: implementation of the Command class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+
+#include "Command.h"
+
+using namespace LOFAR;
+using namespace TBB;
+
+Command::Command() : m_port(0)
+{
+}
+
+Command::~Command()
+{
+}
+
diff --git a/MAC/APL/PIC/TBBDriver/src/Command.h b/MAC/APL/PIC/TBBDriver/src/Command.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a4f44dd6e932a1aa04588c19c6de7f86c7039bd
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/Command.h
@@ -0,0 +1,55 @@
+//#  -*- mode: c++ -*-
+//#
+//#  Command.h: TBB Driver command class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef COMMAND_H_
+#define COMMAND_H_
+
+#include <APL/RTCCommon/Timestamp.h>
+
+#include <Common/LofarTypes.h>
+#include <GCF/TM/GCF_Control.h>
+
+namespace LOFAR {
+  namespace RSP {
+
+    class Command
+    {
+    public:
+
+			// Constructor for Command
+			Command();
+	  
+      // Destructor for Command.
+      virtual ~Command();
+
+
+
+    private:
+      GCFEvent*          m_event;
+      GCFPortInterface*  m_port;
+    };
+  };
+};
+     
+#endif /* COMMAND_H_ */
diff --git a/MAC/APL/PIC/TBBDriver/src/Makefile.am b/MAC/APL/PIC/TBBDriver/src/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..1e60511f80af08559302105d508a03bfdb1f70e6
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/Makefile.am
@@ -0,0 +1,41 @@
+# if HAVE_SHMEM
+# SUBDIRS = shmem .
+# endif
+
+lib_LTLIBRARIES         = libtbbdriver.la
+
+libtbbdriver_la_SOURCES = \
+	BoardCmdHandler.h \
+	BoardCmdHandler.cc \
+	Command.h \
+	Command.cc			
+
+# AM_YFLAGS               = -d -p KeyParse
+# AM_LFLAGS               = -PKeyTokenize
+# LEX_OUTPUT_ROOT         = lex.KeyTokenize
+
+# if HAVE_SHMEM
+# libtbbdriver_la_LIBADD     = shmem/libshmem.la
+# endif
+
+bin_PROGRAMS = TBBDriver
+
+# Lines to build a program prg
+#prg_SOURCES		= prg.cc
+#prg_LDADD		= libtbbdriver.la
+#prg_DEPENDENCIES	= libtbbdriver.la $(LOFAR_DEPEND)
+
+TBBDriver_SOURCES = \
+	TBBDriver.h \
+	TBBDriver.cc
+
+glishdir = $(libexecdir)/glish
+dist_glish_SCRIPTS = 
+
+pythondir = $(bindir)
+dist_python_SCRIPTS = 
+
+scriptdir = $(bindir)
+dist_script_SCRIPTS = 
+
+include $(top_srcdir)/Makefile.common
diff --git a/MAC/APL/PIC/TBBDriver/src/RawEvent.cc b/MAC/APL/PIC/TBBDriver/src/RawEvent.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9dbfc0d1c0db1c4c84595989795818208638b49d
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/RawEvent.cc
@@ -0,0 +1,175 @@
+//#
+//#  RawEvent.cc: implementation of the RawEvent class.
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <GCF/TM/GCF_ETHRawPort.h>
+
+#include <APL/RSP_Protocol/TP_Protocol.ph>
+
+#include "RawEvent.h"
+
+using namespace LOFAR;
+using namespace TP_Protocol;
+
+static const uint8 OPCODE_LEN = 4;
+
+//
+// GCFEvent must be 4byte aligned
+//
+typedef struct {
+	GCFEvent  event;
+	uint32		opcode;
+	uint8     payload[ETH_DATA_LEN-4];
+} RawFrame;
+static RawFrame buf;
+
+
+GCFEvent::TResult RawEvent::dispatch(GCFTask& task, GCFPortInterface& port)
+{
+  
+  GCFEvent::TResult status = GCFEvent::NOT_HANDLED;
+  
+  // Receive a raw packet
+  ssize_t size = port.recv(buf.payload, ETH_DATA_LEN);
+  
+	// at least 4 bytes
+  if (size < OPCODE_LEN) return GCFEvent::NOT_HANDLED;
+  
+	
+  LOG_DEBUG(formatString("F_DATAIN: Opcode=0x%04x",buf.opcode));
+ 
+  //
+  // If no error, lookup buf.opcode number, else assign ACK_ERROR buf.event.signal number
+  //
+  switch(buf.opcode)
+	 {
+	 case TPALLOC:
+  		buf.event.signal = TP_ALLOC;
+  		buf.event.length = 16;
+  		break;
+	 case TPFREE:
+  		buf.event.signal = TP_FREE;
+  		buf.event.length = 8;
+  		break;
+	 case TPRECORD:
+  		buf.event.signal = TP_RECORD;
+  		buf.event.length = 8;
+  		break;
+	 case TPSTOP:
+  		buf.event.signal = TP_RECORD;
+  		buf.event.length = 8;
+  		break;
+	 case TPTRIGGER:
+  		buf.event.signal = TP_TRIGGER;
+  		buf.event.length = 16;
+  		break;
+	 case TPTRIGCLR:
+  		buf.event.signal = TP_TRIGCLR;
+  		buf.event.length = 8;
+  		break;
+	 case TPREAD:
+  		buf.event.signal = TP_READ;
+  		buf.event.length = 16;
+  		break;
+	 case TPUDP:
+  		buf.event.signal = TP_UDP;
+  		buf.event.length = 40;
+  		break;
+	 case TPVERSION:
+  		buf.event.signal = TP_VERSION;
+  		buf.event.length = 36;
+  		break;
+	 case TPSIZE:
+  		buf.event.signal = TP_SIZE;
+  		buf.event.length = 8;
+  		break;
+	 case TPERROR:
+  		buf.event.signal = TP_ERROR;
+  		buf.event.length = 8;
+  		break;
+	 case TPCLEAR:
+  		buf.event.signal = TP_CLEAR;
+  		buf.event.length = 4;
+  		break;
+	 case TPRESET:
+  		buf.event.signal = TP_RESET;
+  		buf.event.length = 4;
+  		break;
+	 case TPCONFIG:
+  		buf.event.signal = TP_CONFIG;
+  		buf.event.length = 8;
+  		break;
+	 case TPERASEF:
+  		buf.event.signal = TP_ERASEF;
+  		buf.event.length = 8;
+  		break;
+	 case TPREADF:
+  		buf.event.signal = TP_READF;
+  		buf.event.length = 1028;
+  		break;
+	 case TPWRITEF:
+  		buf.event.signal = TP_WRITEF;
+  		buf.event.length = 1028;
+  		break;
+	 case TPREADW:
+  		buf.event.signal = TP_READW;
+  		buf.event.length = 20;
+  		break;
+	 case TPWRITEW:
+  		buf.event.signal = TP_WRITEW;
+  		buf.event.length = 20;
+  		break;
+	 default:
+  		buf.event.signal = 0;
+			buf.event.length = 0;
+  		break;
+	 }
+  
+  if (buf.event.signal) // buf.event.signal == 0 indicates unrecognised or invalid MEP message
+	{
+		
+		 (void)new((void*)&buf.event) GCFEvent(buf.event.signal); // placement new does in place construction
+				
+		//
+		// Print debugging info
+		// 
+		LOG_DEBUG(formatString("%s receives '%s' on port '%s'",
+							task.getName().c_str(),
+							task.evtstr(buf.event),
+							port.getName().c_str()));
+				
+		//
+		// dispatch the TP message as a GCFEvent (which it now is)
+		//
+		status = task.dispatch(buf.event, port);
+	}
+  else
+	{
+		LOG_WARN("F_DATAIN: Discarding unknown message.");
+	}
+  
+  return status;
+}
+
+
diff --git a/MAC/APL/PIC/TBBDriver/src/RawEvent.h b/MAC/APL/PIC/TBBDriver/src/RawEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..99292519db09cdc6a88feee49e684faac00a765f
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/RawEvent.h
@@ -0,0 +1,73 @@
+//#  -*- mode: c++ -*-
+//#
+//#  RawEvent.h: dispatch raw EPA events as GCF events.
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef RAWEVENT_H_
+#define RAWEVENT_H_
+
+#include <GCF/TM/GCF_Control.h>
+
+namespace LOFAR {
+  namespace TP_Protocol{
+		
+		// TP Command Opcode's
+		// Data Recording
+		static const uint32 TPALLOC   = 0x00000100;  // OUT allocate buffer space to a certain input channel
+		static const uint32 TPFREE    = 0x00000101;  // OUT free buffer settings and disable input channel 
+		static const uint32 TPRECORD  = 0x00000102;  // OUT record channel
+		static const uint32 TPSTOP    = 0x00000103;  // OUT freeze channel
+		// Triggering
+		static const uint32 TPTRIGGER = 0x00000200;  // IN trigger detected
+		static const uint32 TPTRIGCLR = 0x00000201;  // OUT clear trigger flag
+		// Data reading
+		static const uint32 TPREAD    = 0x00000300;  // OUT send recorded data to CEP
+		static const uint32 TPUDP     = 0x00000301;  // OUT configure UDP and IP header
+		// Board information
+		static const uint32 TPVERSION = 0x00000701;  // IN/OUT returns board version
+		static const uint32 TPSIZE    = 0x00000702;  // IN/OUT returns TBB memory size
+		// Board status
+		static const uint32 TPERROR   = 0x00000703;  // IN error on TBB board
+		// Board control
+		static const uint32 TPCLEAR   = 0x00000710;  // OUT clear registers
+		static const uint32 TPRESET   = 0x00000711;  // OUT reset to facory image
+		static const uint32 TPCONFIG  = 0x00000712;  // OUT reconfigure image
+		// Remote system update
+		static const uint32 TPERASEF  = 0x00000720;  // OUT erase flash memory
+		static const uint32 TPREADF   = 0x00000721;  // IN/OUT read flash memory
+		static const uint32 TPWRITEF  = 0x00000722;  // OUT write flash memory
+		// DDR2 acces
+		static const uint32 TPREADW   = 0x00000730;  // IN/OUT read 64bit word from mp
+		static const uint32 TPWRITEW  = 0x00000731;  // OUT write 64bit wort to mp
+		// Direct register acces 
+		static const uint32 TPREADR   = 0x00000740;  // IN/OUT read register(direct access), for debug purpose
+		static const uint32 TPWRITER  = 0x00000741;  // OUT write register(direct access), for debug purpose
+		
+		class RawEvent
+		{
+			public:
+				static LOFAR::GCF::TM::GCFEvent::TResult dispatch(LOFAR::GCF::TM::GCFTask& task,
+																				LOFAR::GCF::TM::GCFPortInterface& port);
+		};
+  };
+};
+#endif /* RAWEVENT_H_ */
diff --git a/MAC/APL/PIC/TBBDriver/src/RemoteStation.conf.in b/MAC/APL/PIC/TBBDriver/src/RemoteStation.conf.in
new file mode 100644
index 0000000000000000000000000000000000000000..187ce610c8bf32f751b2fb9820454cdf493bd3d4
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/RemoteStation.conf.in
@@ -0,0 +1,14 @@
+#
+# Configuration description of the LOFAR remote station TBB boards.
+#
+
+#
+# Number of TBB boards, normal 12
+#
+RS.N_TBBBOARDS=1
+
+#
+# Number of Mp's (Memmory Processors) per TBB board
+#
+RS.N_MPS=4
+
diff --git a/MAC/APL/PIC/TBBDriver/src/StationSettings.cc b/MAC/APL/PIC/TBBDriver/src/StationSettings.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ccc4021c11192f3c23f780cfaba5fc326b6ceb5f
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/StationSettings.cc
@@ -0,0 +1,113 @@
+//#  StationSettings.cc: Global station settings
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <APL/RSP_Protocol/EPA_Protocol.ph>
+#include <StationSettings.h>
+
+namespace LOFAR {
+  namespace RSP {
+
+//
+// Initialize singleton
+//
+StationSettings* StationSettings::theirStationSettings = 0;
+
+StationSettings* StationSettings::instance()
+{
+	if (theirStationSettings == 0) {
+		theirStationSettings = new StationSettings();
+	}
+	return (theirStationSettings);
+}
+
+//
+// Default constructor
+//
+StationSettings::StationSettings() :
+	itsMaxRspBoards(0),
+	itsNrBlpsPerBoard(0),
+	itsNrRcusPerBoard(0),
+	itsNrRspBoards(0),
+	itsNrBlps(0),
+	itsNrRcus(0)
+{
+
+}
+
+//
+// setNrBlpsPerBoard
+//
+void StationSettings::setNrBlpsPerBoard (int32 nrBlps)
+{
+	itsNrBlpsPerBoard = nrBlps;
+	itsNrRcusPerBoard = itsNrBlpsPerBoard * MEPHeader::N_POL;
+	itsNrBlps         = itsNrBlpsPerBoard * itsNrRspBoards;
+	itsNrRcus         = itsNrRcusPerBoard * itsNrRspBoards;
+}
+
+//
+// setNrRspBoards
+//
+void StationSettings::setNrRspBoards    (int32 nrRspBoards)
+{
+	itsNrRspBoards = nrRspBoards;
+	ASSERTSTR (itsNrRspBoards <= itsMaxRspBoards, 
+			formatString("Range conflict in nr of RSP boards (%d<=%d)",
+			itsNrRspBoards, itsMaxRspBoards));
+
+	itsNrBlps      = itsNrBlpsPerBoard * itsNrRspBoards;
+	itsNrRcus      = itsNrRcusPerBoard * itsNrRspBoards;
+}
+
+//
+// setMaxRspBoards
+//
+void StationSettings::setMaxRspBoards   (int32 nrRspBoards)
+{
+	itsMaxRspBoards = nrRspBoards;
+	ASSERTSTR (itsNrRspBoards <= itsMaxRspBoards, 
+			formatString("Rangeconflict in nr of RSP boards (%d<=%d)",
+			itsNrRspBoards, itsMaxRspBoards));
+}
+
+//
+// print
+//
+ostream& StationSettings::print (ostream& os) const
+{
+	os << "Max RSPboards: " << itsMaxRspBoards   << endl;
+	os << "Nr RSPboards : " << itsNrRspBoards    << endl;
+	os << "Nr BLPs/board: " << itsNrBlpsPerBoard << endl;
+	os << "Nr RCUs/board: " << itsNrRcusPerBoard << endl;
+	os << "Nr BLPs      : " << itsNrBlps         << endl;
+	os << "Nr RCUs      : " << itsNrRcus         << endl;
+
+	return (os);
+}
+
+  } // namespace PACKAGE
+} // namespace LOFAR
diff --git a/MAC/APL/PIC/TBBDriver/src/StationSettings.h b/MAC/APL/PIC/TBBDriver/src/StationSettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..18c06a3fe99c6d18db0d42f95c45f86ad6980b12
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/StationSettings.h
@@ -0,0 +1,100 @@
+//#  StationSettings.h: Global station settings
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef LOFAR_TBB_STATIONSETTINGS_H
+#define LOFAR_TBB_STATIONSETTINGS_H
+
+// \file StationSettings.h
+// Global station settings
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+#include <Common/LofarTypes.h>
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+  namespace TBB {
+
+// \addtogroup RSP
+// @{
+
+// forward declaration
+class TBBDriver;
+
+// class_description
+// ...
+class StationSettings
+{
+public:
+	StationSettings ();
+	~StationSettings() {};
+
+	static StationSettings* instance();
+
+	int32 maxTbbBoards();	// RS.N_RSPBOARDS
+	
+	int32 nrTbbBoards();	// 1 | RS.N_RSPBOARDS depending on OPERATION_MODE
+	
+	ostream& print (ostream& os) const;
+
+	friend class TBBDriver;
+
+protected:	// note TBBDriver must be able to set them
+	void setNrTbbBoards    (int32 nrBlps);
+	void setMaxTbbBoards   (int32 nrBlps);
+
+private:
+	// Copying is not allowed
+	StationSettings(const StationSettings&	that);
+	StationSettings& operator=(const StationSettings& that);
+
+	//# --- Datamembers ---
+	int32	itsMaxTbbBoards;	// constants
+	int32	itsNrMpsPerBoard;
+	int32	itsNrTbbBoards;		// values depend on OPERATION_MODE
+	int32	itsNrMp;					// values depend on OPERATION_MODE
+	
+	static StationSettings* theirStationSettings;
+};
+
+//# --- inline functions ---
+inline	int32 StationSettings::maxTbbBoards()	{ return (itsMaxTbbBoards);   }
+inline	int32 StationSettings::nrMpsPerBoard() { return (itsNrMpsPerBoard); }
+
+inline	int32 StationSettings::nrTbbBoards()	{ return (itsNrTbbBoards); }
+inline	int32 StationSettings::nrMp()		{ return (itsNrMp); }
+
+
+//#
+//# operator<<
+//#
+inline ostream& operator<< (ostream& os, const StationSettings& aSS)
+{	
+	return (aSS.print(os));
+}
+
+// @}
+  } // namespace RSP
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc b/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
new file mode 100644
index 0000000000000000000000000000000000000000..62b992ace81606c031ea24f8384d7292392bd846
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
@@ -0,0 +1,525 @@
+//#  TBBDriver.cc: one line description
+//# 
+//#  Copyright (C) 2006
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <TBBDriver.h>
+// include all cmd and msg classes
+#include <AllocCmd.h>
+#include <FreeCmd.h>
+#include <RecordCmd.h>
+#include <Stop.h>
+#include <TrigclrCmd.h>
+#include <ReadCmd.h>
+#include <UdpCmd.h>
+#include <VersionCmd.h>
+#include <SizeCmd.h>
+#include <ClearCmd.h>
+#include <ResetCmd.h>
+#include <ConfigCmd.h>
+#include <ErasefCmd.h>
+#include <ReadfCmd.h>
+#include <WritefCmd.h>
+#include <ReadwCmd.h>
+#include <WritewCmd.h>
+#include <TriggerMsg.h>
+#include <ErrorMsg.h>
+
+
+#define ETHERTYPE_TP 0x10FA			// first 4 letters of LOFAr
+
+namespace LOFAR;
+namespace TBB;
+
+//
+// parseOptions
+//
+void parseOptions(int argc, char** argv)
+{
+  
+	static struct option long_options[] = {
+		{ "instance",   required_argument, 0, 'I' },
+		{ "daemon",     no_argument,       0, 'd' },
+		{ 0, 0, 0, 0 }
+	};
+
+	optind = 0; // reset option parsing
+	for(;;)
+	{
+		int option_index = 0;
+		int c = getopt_long(argc, argv, "dI:", long_options, &option_index);
+
+		if (c == -1)
+		{
+			break;
+		}
+
+		switch (c)
+		{
+			case 'I':   // --instance
+				g_instancenr = atoi(optarg);
+				break;
+			case 'd':   // --daemon
+				g_daemonize = true;
+				break;
+			default:
+				LOG_FATAL (formatString("Unknown option %c", c));
+				ASSERT(false);
+		}
+	}
+}
+		
+TBBDriver::TBBDriver(string name)
+  : GCFTask((State)&TBBDriver::initial, name), m_board(0)
+{
+  // first initialize the global settins
+  LOG_DEBUG("Setting up station settings");
+  StationSettings*      ssp = StationSettings::instance();
+  ssp->setMaxTbbBoards  (GCF::ParamterSet::instance()->getInt("RS.N_TBBBOARDS"));
+  ssp->setNrTbbBoards   (GCF::ParamterSet::instance()->getInt("RS.N_RSPBOARDS"));
+
+  if (GET_CONFIG("TBBDriver.OPERATION_MODE", i) == MODE_SUBSTATION) {
+	 ssp->setNrTbbBoards(1);
+  };
+  ASSERTSTR (g_instancenr <= StationSettings::instance()->maxTbbBoards(),
+				 "instancenumber larger than MAX_TBBBOARDS");
+  ASSERTSTR ((GET_CONFIG("TBBDriver.OPERATION_MODE" ,i) == MODE_SUBSTATION) == 
+				 (g_instancenr != -1), 
+				 "--instance option does not match OPERATION_MODE setting");
+  LOG_DEBUG_STR (*ssp);
+
+  // tell broker we are here
+  LOG_DEBUG("Registering protocols");
+  registerProtocol(TBB_PROTOCOL, TBB_PROTOCOL_signalnames);
+  registerProtocol(TP_PROTOCOL, TP_PROTOCOL_signalnames);
+
+  // open client port
+  LOG_DEBUG("Opening listener for clients");
+  string  acceptorID;
+  if (g_instancenr>=0) {
+	 acceptorID = formatString("(%d)", g_instancenr);
+  }
+  m_acceptor.init(*this, "acceptor_v3"+acceptorID, GCFPortInterface::MSPP, TBB_PROTOCOL);
+
+  // open port with TBB board
+  LOG_DEBUG("Connecting to TBB boards");
+  m_board = new GCFETHRawPort[StationSettings::instance()->nrTbbBoards()];
+  ASSERT(m_board);
+
+  //
+  // Attempt access of TBBDriver.MAC_BASE, if it fails use the TBBDriver.ADDR0
+  // parameters.
+  //
+  bool bUseMAC_BASE = true;
+  try
+	 {
+	 
+		(void)GCF::ParamterSet::instance()->getInt("TBBDriver.MAC_BASE"); 
+	 }
+  catch (...)
+	 {
+		bUseMAC_BASE = false;
+	 }
+
+  char boardname[64];
+  char paramname[64];
+  char macaddrstr[64];
+  for (int boardid = 0; boardid < StationSettings::instance()->nrTbbBoards(); boardid++)
+	 {
+		snprintf(boardname, 64, "board%d", boardid);
+		
+		if (bUseMAC_BASE)
+		  {
+			 snprintf(macaddrstr, 64, "00:00:00:00:00:%02x", boardid + GCF::ParamterSet::instance()->getInt("TBBDriver.MAC_BASE"));
+		  }
+		else
+		  {
+			 snprintf(paramname, 64, "TBBDriver.MAC_ADDR_%d", boardid);
+			 strncpy(macaddrstr, GET_CONFIG_STRING(paramname), 64);
+		  }
+
+		LOG_DEBUG_STR("initializing board " << boardname << ":" << macaddrstr);
+		m_board[boardid].init(*this, boardname, GCFPortInterface::SAP, TP_PROTOCOL,true /*raw*/);
+		m_board[boardid].setAddr(GET_CONFIG_STRING("TBBDriver.IF_NAME"), macaddrstr);
+		
+		// set ethertype to 0x10FA so Ethereal can decode EPA messages
+		m_board[boardid].setEtherType(ETHERTYPE_TP);
+	 }
+}
+
+
+TBBDriver::~TBBDriver()
+{
+  //
+}
+
+//
+// idle(event, port)
+//
+GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
+{
+	GCFEvent::TResult status = GCFEvent::HANDLED;
+  
+	switch(event.signal)
+	{
+		case F_INIT: {
+		}	break;
+        
+		case F_ENTRY:	{
+			if(!tp_queue_emty)
+			{
+				SetTpCommand(event);
+				status = ClientAction.dispatch(event,port);
+				
+				TRAN(TBBDriver::busy);
+			}
+			
+			if(!tbb_queue_emty)
+			{
+				SetTbbCommand(event);
+				status = boardAction.dispatch(event,port);
+				
+				TRAN(TBBDriver::busy);
+			}
+		}	break;
+        
+		case F_CONNECTED:	{
+			LOG_INFO(formatString("CONNECTED: port '%s'", port.getName().c_str()));
+		}	break;
+		
+		case F_DISCONNECTED: {
+		}	break;
+				
+		case F_TIMER:	{
+		}	break;
+				
+		case F_DATAIN: {
+			status = RawEvent::dispatch(*this, port);	
+		}	break;
+			
+		case F_EXIT: {
+		}	break;
+		
+		case TBB_ALLOC:	
+		case TBB_FREE:
+		case TBB_RECORD: 
+		case TBB_STOP:
+		case TBB_TRIGCLR:
+		case TBB_READ:
+		case TBB_UDP:
+		case TBB_VERSION:
+		case TBB_SIZE:
+		case TBB_CLEAR:
+		case TBB_RESET:
+		case TBB_CONFIG:
+		case TBB_ERASEF:
+		case TBB_READF:
+		case TBB_WRITEF:
+		case TBB_READW:
+		case TBB_WRITEW:
+		{
+			SetTbbCommand(event); 
+			status = BoardAction.dispatch(event,port);
+			 
+			TRAN(TBBDriver::busy_state);
+		} break;
+		
+		case TP_TRIGGER:
+		case TP_ERROR:
+		{
+			SetTpCommand(event);
+			status = ClientAction.dispatch(event,port);
+			
+			TRAN(TBBDriver::busy);
+		}	break;		
+		
+		default: {
+			status = GCFEvent::NOT_HANDLED;
+		}	break;
+	}
+	return status;
+}
+
+//
+// enabled(event, port)
+//
+GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
+{
+	GCFEvent::TResult status = GCFEvent::HANDLED;    
+	
+	switch(event.signal)
+	{
+		case F_ENTRY: {
+		}	break;
+		
+		case F_ACCEPT_REQ: {
+		}	break;
+		
+		case F_CONNECTED:	{
+		}	break;
+		
+		case F_DATAIN: {
+			status = RawEvent::dispatch(*this, port);
+		}	break;
+		
+		case TBB_ALLOC:	
+		case TBB_FREE:
+		case TBB_RECORD: 
+		case TBB_STOP:
+		case TBB_TRIGCLR:
+		case TBB_READ:
+		case TBB_UDP:
+		case TBB_VERSION:
+		case TBB_SIZE:
+		case TBB_CLEAR:
+		case TBB_RESET:
+		case TBB_CONFIG:
+		case TBB_ERASEF:
+		case TBB_READF:
+		case TBB_WRITEF:
+		case TBB_READW:
+		case TBB_WRITEW:
+		{
+			// put event on tbb queue
+		}	break;	
+			
+		case TP_TRIGGER:
+		case TP_ERROR:
+		{
+			// put event on tp queue
+		}	break;		
+		
+		case TP_ALLOC:	
+		case TP_FREE:
+		case TP_RECORD: 
+		case TP_STOP:
+		case TP_TRIGCLR:
+		case TP_READ:
+		case TP_UDP:
+		case TP_VERSION:
+		case TP_SIZE:
+		case TP_CLEAR:
+		case TP_RESET:
+		case TP_CONFIG:
+		case TP_ERASEF:
+		case TP_READF:
+		case TP_WRITEF:
+		case TP_READW:
+		case TP_WRITEW:
+		{
+			status = BoardAction.dispatch(event,port); // dispatch ack from boards
+		}	break;	
+		
+		case TBB_TRIGGERACK:
+		case TBB_ERRORACK:
+		{
+			status = ClientAction.dispatch(event,port); // dispatch ack from client
+		}	break;		
+			
+		case F_TIMER:	{
+		} break;
+		
+		case F_DISCONNECTED: {
+		}	break;
+		
+		case F_EXIT: {
+		} break;
+		
+		default: {
+			status = GCFEvent::NOT_HANDLED;
+		}	break;
+	}
+	return status;
+}
+
+
+bool TBBDriver::SetTbbCommand(GCFEvent& event)
+{
+	cmd = 0;
+	switch(event.signal)
+	{
+		case TBB_ALLOC:	{
+			AllocCmd *cmd = AllocCmd();
+		} break;
+		
+		case TBB_FREE:	{
+			FreeCmd *cmd = FreeCmd();
+		} break;
+		
+		case TBB_RECORD: 	{
+			RecordCmd *cmd = RecordCmd();
+		} break;
+		
+		case TBB_STOP:	{
+			Stopcmd *cmd = StopCmd();
+		} break;
+		
+		case TBB_TRIGCLR:	{
+			TrigclrCmd *cmd = TrigclrCmd();
+		} break;
+		
+		case TBB_READ:	{
+			ReadCmd *cmd = ReadCmd();
+		} break;
+		
+		case TBB_UDP: {
+			UdpCmd *cmd = UdpCmd();
+		} break;
+		
+		case TBB_VERSION: {
+			VersionCmd *cmd = VersionCmd();
+		} break;
+		
+		case TBB_SIZE:	{
+			SizeCmd *cmd = SizeCmd();
+		} break;
+		
+		case TBB_CLEAR:	{
+			ClearCmd *cmd = ClearCmd();
+		} break;
+		
+		case TBB_RESET:	{
+			ResetCmd *cmd = ResetCmd();
+		} break;
+		
+		case TBB_CONFIG:	{
+			ConfigCmd *cmd = ConfigCmd();
+		} break;
+		
+		case TBB_ERASEF:	{
+			ErasefCmd *cmd = ErasefCmd();
+		} break;
+		
+		case TBB_READF:	{
+			ReadfCmd *cmd = ReadfCmd();
+		} break;
+		
+		case TBB_WRITEF:
+		{
+			WritefCmd *cmd = WritefCmd();
+		} break;
+		
+		case TBB_READW: {
+			ReadwCmd *cmd = ReadwCmd();
+		} break;
+		
+		case TBB_WRITEW:	{
+			WritewCmd *cmd = WritewCmd();
+		} break; 
+	}
+	if(cmd)
+	{
+		BoardAction.SetCommand(cmd);
+		return true;
+	}
+	return false;
+}
+
+
+bool TBBDriver::SetTpCommand(GCFEvent& event)
+{
+	cmd = 0;
+	switch(event.signal)
+	{
+		case TP_TRIGGER: {
+			TriggerMsg *cmd = TriggerMsg();
+		} break;
+		
+		case TP_ERROR:	{
+			ErrorMsg *cmd = ErrorMsg();
+		} break; 
+	}
+	if(cmd)
+	{
+		Client.SetCommand(cmd);
+		return true;
+	}
+	return false;
+}
+
+        
+//
+// main (argc, argv)
+//
+int main(int argc, char** argv)
+{
+  GCFTask::init(argc, argv);    // initializes log system
+  
+  LOG_INFO(formatString("Starting up %s", argv[0]));
+  
+  // adopt commandline switches
+  LOG_DEBUG("Parsing options");
+  parseOptions (argc, argv);
+  
+  // daemonize if required 
+  if (g_daemonize) {
+	 if (0 != daemonize(false)) {
+		cerr << "Failed to background this process: " << strerror(errno) << endl;
+		exit(EXIT_FAILURE);
+	 }
+  }
+  
+  LOG_DEBUG ("Reading configuration files");
+  try
+	 {
+		GCF::ParameterSet::instance()->adoptFile("TBBDriverPorts.conf");
+		GCF::ParameterSet::instance()->adoptFile("RemoteStation.conf");
+	 }
+  catch (Exception e)
+	 {
+		LOG_ERROR_STR("Failed to load configuration files: " << e.text());
+		exit(EXIT_FAILURE);
+	 }
+  
+  TBBDriver tbb("TBBDriver");
+  
+  tbb.start(); // make initial transition
+  
+  try
+	 {
+		GCFTask::run();
+	 }
+  catch (Exception e)
+	 {
+		LOG_ERROR_STR("Exception: " << e.text());
+		exit(EXIT_FAILURE);
+	 }
+  
+  LOG_INFO("Normal termination of program");
+  
+  return 0;
+}
+
+// Remove lines or remove comments for copy constructor and assignment.
+///TBBDriver::TBBDriver (const TBBDriver& that)
+///{}
+///TBBDriver& TBBDriver::operator= (const TBBDriver& that)
+///{
+///  if (this != &that) {
+///    ... copy members ...
+///  }
+///  return *this;
+///}
+
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in b/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in
new file mode 100644
index 0000000000000000000000000000000000000000..396766823e950f16d45fc887ac40287516f65e91
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in
@@ -0,0 +1,123 @@
+#
+# Configuration of the TBBDriver
+#
+
+#
+# Specify the base index of the TBB board ethernet MAC address
+# The TBB boards addresses will be numbered consecutively.
+#
+# Start from address: 00:00:00:00:00:MAC_BASE
+# TBBDriver.MAC_BASE=1
+
+#
+# Instead of specifying MAC_BASE, one can specify all MAC
+# addresses explicitly as MAC_ADDR0..MAC_ADDR11
+# In this case you must leave TBBDriver.MAC_BASE unspecified
+#
+#TBBDriver.MAC_ADDR_0=00:00:00:00:00:08
+#lofar27:eth2:00:50:04:32:B8:5C
+#TBBDriver.MAC_ADDR_0=00:50:04:32:B8:5C
+
+TBBDriver.MAC_ADDR_0=10:FA:00:00:13:00
+TBBDriver.MAC_ADDR_1=10:FA:00:00:12:00
+TBBDriver.MAC_ADDR_2=00:00:00:00:00:03
+TBBDriver.MAC_ADDR_3=00:00:00:00:00:04
+TBBDriver.MAC_ADDR_4=00:00:00:00:00:05
+TBBDriver.MAC_ADDR_5=00:00:00:00:00:06
+TBBDriver.MAC_ADDR_6=00:00:00:00:00:07
+TBBDriver.MAC_ADDR_7=00:00:00:00:00:08
+TBBDriver.MAC_ADDR_8=00:00:00:00:00:09
+TBBDriver.MAC_ADDR_9=00:00:00:00:00:10
+TBBDriver.MAC_ADDR_10=00:00:00:00:00:0A
+TBBDriver.MAC_ADDR_11=00:00:00:00:00:0B
+
+#
+# Data output payload size.
+# Should eventually be computed dynamically
+# based on settings.
+#
+TBBDriver.OUTPUT_PAYLOAD_SIZE=736
+
+#
+# Destination IP and MAC address for data packets
+# leaving the RSP board with the given index
+#
+#
+# Output to lofar11
+#
+
+TBBDriver.SRC_IP_ADDR_0=10.1.0.1
+TBBDriver.DST_IP_ADDR_0=192.168.2.111
+TBBDriver.DST_MAC_ADDR_0=00:04:23:B5:C4:6A
+
+#
+# Output to lofar12
+#
+TBBDriver.SRC_IP_ADDR_1=10.1.0.2
+TBBDriver.DST_IP_ADDR_1=192.168.2.112
+TBBDriver.DST_MAC_ADDR_1=00:04:23:B5:C5:CA
+
+TBBDriver.SRC_IP_ADDR_2=10.1.0.3
+TBBDriver.DST_IP_ADDR_2=10.2.0.3
+TBBDriver.DST_MAC_ADDR_2=
+TBBDriver.SRC_IP_ADDR_3=10.1.0.4
+TBBDriver.DST_IP_ADDR_3=10.2.0.4
+TBBDriver.DST_MAC_ADDR_3=
+TBBDriver.SRC_IP_ADDR_4=10.1.0.5
+TBBDriver.DST_IP_ADDR_4=10.2.0.5
+TBBDriver.DST_MAC_ADDR_4=
+TBBDriver.SRC_IP_ADDR_5=10.1.0.6
+TBBDriver.DST_IP_ADDR_5=10.2.0.6
+TBBDriver.DST_MAC_ADDR_5=
+TBBDriver.SRC_IP_ADDR_6=10.1.0.7
+TBBDriver.DST_IP_ADDR_6=10.2.0.7
+TBBDriver.DST_MAC_ADDR_6=
+TBBDriver.SRC_IP_ADDR_7=10.1.0.8
+TBBDriver.DST_IP_ADDR_7=10.2.0.8
+TBBDriver.DST_MAC_ADDR_7=
+TBBDriver.SRC_IP_ADDR_8=10.1.0.9
+TBBDriver.DST_IP_ADDR_8=10.2.0.9
+TBBDriver.DST_MAC_ADDR_8=
+TBBDriver.SRC_IP_ADDR_9=10.1.0.10
+TBBDriver.DST_IP_ADDR_9=10.2.0.10
+TBBDriver.DST_MAC_ADDR_9=
+TBBDriver.SRC_IP_ADDR_10=10.1.0.11
+TBBDriver.DST_IP_ADDR_10=10.2.0.11
+TBBDriver.DST_MAC_ADDR_10=
+TBBDriver.SRC_IP_ADDR_11=10.1.0.12
+TBBDriver.DST_IP_ADDR_11=10.2.0.12
+TBBDriver.DST_MAC_ADDR_11=
+
+#
+# Ethernet interface on which to contact the RSP boards.
+# This interface would normally be connected to the switch.
+#
+TBBDriver.IF_NAME=eth1
+
+#
+# Select LOOPBACK_MODE mode
+#
+# If LOOPBACK_MODE == 0, the WRITE is done first.
+# In this mode the TBBDriver checks that what was
+# written is correctly read back from the board. This can
+# be used to check that the RSP board or the EPAStub
+# functions correctly. Read results are not stored in
+# the TBBDriver cache.
+#
+# If LOOPBACK_MODE == 1, the READ is done first.
+# In this mode you can check with Ethereal that what was
+# read from the RSP board or EPAStub is written back in
+# the same way. This is used to check whether the TBBDriver
+# stores the information at the correct location in its cache.
+# Of course in this mode reads results are stored in the
+# TBBDriver cache.
+#
+TBBDriver.LOOPBACK_MODE=0
+
+#
+# Specify how the TBBDriver should operate:
+# 0: one RSP driver active --> control all boards
+# 1: many RSP drivers active --> control boards -I<n> only
+#
+TBBDriver.OPERATION_MODE=0
+
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.h b/MAC/APL/PIC/TBBDriver/src/TBBDriver.h
new file mode 100644
index 0000000000000000000000000000000000000000..568e28f9bee25ca50746c5f88049851e06193e05
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.h
@@ -0,0 +1,85 @@
+//#  TBBDriver.h: Driver for the TBB board
+//#
+//#  Copyright (C) 2006
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef LOFAR_TBBDRIVER_TBBDRIVER_H
+#define LOFAR_TBBDRIVER_TBBDRIVER_H
+
+#include <APL/TBB_Protocol/TBB_Protocol.ph>
+#include <APL/TBB_Protocol/TP_Protocol.ph>
+
+#include <GCF/TM/GCF_Control.h>
+#include <GCF/TM/GCF_ETHRawPort.h>
+#include <GCF/TM/GCF_DevicePort.h>
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+
+namespace LOFAR{
+  namespace TBB{
+	 
+    // Description of class.
+    class TBBDriver
+    {
+    public:
+		
+			// The constructor of the TBBDriver task.
+			// @param name The name of the task. The name is used for looking
+			// up connection establishment information using the GTMNameService and
+			// GTMTopologyService classes.
+			TBBDriver(string name);
+      ~TBBDriver();
+		
+      // The idle state. 
+			// This state is used to wait for events from the client
+      // and board ports. When a event is received the command is executed 
+			// and transition to the busy state is made.
+      GCFEvent::TResult idle_state(GCFEvent& event, GCFPortInterface &port);
+		
+      // The busy state.
+			// In this state the task can receive TBBEvents,
+			// but they will be put on the que.
+			// All TPEvent will be transmittted imediallie
+      GCFEvent::TResult busy_state(GCFEvent& event, GCFPortInterface &port);
+		
+		
+    private:
+      // Copying is not allowed ??
+      TBBDriver (const TBBDriver& that);
+      TBBDriver& operator= (const TBBDriver& that);
+		
+			bool SetTbbCommand(GCFEvent& event);
+			bool SetTpCommand(GCFEvent& event);
+			
+			// define some constants
+	  	// mode of operation
+
+			static const int32	MODE_NORMAL	    = 0; // control all RSPboards
+			static const int32	MODE_SUBSTATION = 1; // control only one RSPboard
+			
+			GCFTCPPort                   m_acceptor;     // listen for clients on this port
+			GCFETHRawPort*               m_board;        // array of ports, one for each RSP board
+			std::list<GCFPortInterface*> m_client_list;  // list of clients
+			std::list<GCFPortInterface*> m_dead_clients; // list of clients to cleanup
+    };
+  } // namespace TBB
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriverPorts.conf.in b/MAC/APL/PIC/TBBDriver/src/TBBDriverPorts.conf.in
new file mode 100644
index 0000000000000000000000000000000000000000..307d80228eb468dc512027fab933712f8a3bd55e
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriverPorts.conf.in
@@ -0,0 +1,17 @@
+#
+# Configuration of the TBBDriver communication ports.
+#
+
+#
+# TBBDriver configuration
+#
+mac.ns.TBBDriver.server.type=TCP
+#mac.ns.TBBDriver.spid.port=0
+mac.ns.TBBDriver.spid.deviceName=/dev/spid0
+mac.ns.TBBDriver.acceptor_v3.type=TCP
+
+#
+# TBBTest configuration
+#
+mac.ns.TBBTest.server.type=TCP
+mac.top.TBBTest.server.remoteservice=TBBDriver:acceptor_v3
diff --git a/MAC/APL/PIC/TBBDriver/src/VersionCmd.cc b/MAC/APL/PIC/TBBDriver/src/VersionCmd.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c8dda6e5dfa65f77a81f14225a3609664a480820
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/VersionCmd.cc
@@ -0,0 +1,138 @@
+//#  GetVersions.cc: implementation of the GetVersions class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+
+#include <APL/TBB_Protocol/TBB_Protocol.ph>
+#include <APL/TBB_Protocol/TP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+#include <blitz/array.h>
+
+#include "GetVersions.h"
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace TBB;
+using namespace TBB_Protocol;
+using namespace TP_Protocol;
+using namespace RTC;
+
+GetVersions::GetVersions(GCFEvent& event, GCFPortInterface& port)
+	: BoardAction(board_port, board_id, StationSettings::instance()->nrBlpsPerBoard() + 1 /* BP */)
+{
+	// TODO
+}
+
+GetVersions::~GetVersionsCmd()
+{
+	// TODO
+}
+
+
+void GetVersions::tp_buildrequest()
+{
+	tp_event.opcode = VERSION;
+}
+
+void GetVersions::tp_sendrequest(GCFPortInterface& port)
+{
+	port.send(tp_event);
+}
+
+
+GCFEvent::TResult GetVersions::tp_handleack(GCFEvent& event, GCFPortInterface& port)
+{
+	if (TP_VERSION != event.signal)
+	{
+		LOG_WARN("GetVersions::handleack: unexpected ack");
+		return GCFEvent::NOT_HANDLED;
+	}
+  
+	EPARsrVersionEvent ack(event);
+
+	if (!ack.hdr.isValidAck(m_hdr))
+	{
+		LOG_ERROR("VersionsRead::handleack: invalid ack");
+		return GCFEvent::NOT_HANDLED;
+	}
+
+	if (MEPHeader::DST_RSP == ack.hdr.m_fields.addr.dstid) {
+
+		Cache::getInstance().getBack().getVersions().bp()(getBoardId()) = ack.version;
+
+	} else {
+
+		int ap_index = -1;
+		switch (ack.hdr.m_fields.addr.dstid) {
+			case MEPHeader::DST_BLP0:
+				ap_index = 0;
+				break;
+			case MEPHeader::DST_BLP1:
+				ap_index = 1;
+				break;
+			case MEPHeader::DST_BLP2:
+				ap_index = 2;
+				break;
+			case MEPHeader::DST_BLP3:
+				ap_index = 3;
+				break;
+			default:
+				LOG_WARN("Invalid BLP in EPARsrVersionEvent");
+				break;
+		}
+
+		if (ap_index >= 0) {
+			Cache::getInstance().getBack().getVersions().ap()((getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + ap_index)
+					= ack.version;  
+		}
+	}
+	return GCFEvent::HANDLED;
+}
+
+
+
+void GetVersions::tbb_sendack()
+{
+	tbb_ackevent.status = SUCCESS;
+	
+	tbb_ackevent.tbbversion[tbbnr].boardid = ;
+	tbb_ackevent.tbbversion[tbbnr].swversion = ;
+	
+	getPort()->send(tbb_ackevent);
+}
+
+void GetVersionsCmd::apply(CacheBuffer& /*cache*/, bool /*setModFlag*/)
+{
+  // intentionally left empty 
+}
+
+void GetVersionsCmd::complete(CacheBuffer& cache)
+{
+	ack(cache);
+}
+
+bool GetVersionsCmd::validate() const
+{
+	return true;
+}
+
diff --git a/MAC/APL/PIC/TBBDriver/src/VersionCmd.h b/MAC/APL/PIC/TBBDriver/src/VersionCmd.h
new file mode 100644
index 0000000000000000000000000000000000000000..02863513c80bcfdd8cbbbf1b1a880da4c3ed9ded
--- /dev/null
+++ b/MAC/APL/PIC/TBBDriver/src/VersionCmd.h
@@ -0,0 +1,86 @@
+//#  -*- mode: c++ -*-
+//#
+//#  GetVersions.h: Get Tbb board versions
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef GETVERSIONS_H_
+#define GETVERSIONS_H_
+
+#include "BoardAction.h"
+#include <APL/TBB_Protocol/TBB_Protocol.ph>
+#include <APL/TBB_Protocol/TP_Protocol.ph>
+
+#include <Common/LofarTypes.h>
+#include <GCF/TM/GCF_Control.h>
+
+namespace LOFAR {
+  namespace TBB {
+
+		class GetVersions : public BoardAction 
+		{
+			public:
+				/// Constructors for a GetVersions object.
+				GetVersionsCmd(GCFEvent& event);
+	  
+				/// Destructor for GetVersions.
+				virtual ~GetVersionsCmd();
+				
+				/// Build the message that will be send to the board
+				///
+				virtual void tp_buildrequest();
+				
+				/// send the message to the given port
+				///
+				virtual void tp_sendrequest(GCFPortInterface& port);
+				
+				/// wait for response from the boards
+				///
+				virtual GCFEvent::TResult tp_handleack(GCFEvent& event, GCFPortInterface& /*port*/);
+						
+				/// Acknowledge the command by sending the appropriate
+				/// response on m_port.
+				virtual void tbb_sendack();
+				
+				/// Make necessary changes to the cache for the next synchronization.
+				/// Any changes will be sent to the RSP boards.
+				virtual void apply();
+
+				/// Complete the command by sending the appropriate response on
+				/// the m_answerport;
+				virtual void complete();
+
+
+				/// Validate the event that underlies the command.
+				virtual bool validate() const;
+
+      
+			private:
+				GetVersions();
+
+				TBBVersionEvent 		tbb_event;
+				TBBVersionackEvent	tbb_ackevent;
+				TPVersionEvent			tp_event;
+		};
+	};
+};
+
+#endif /* GETVERSIONS_H_ */