Index: trunk/FACT++/src/fadctrl.cc
===================================================================
--- trunk/FACT++/src/fadctrl.cc	(revision 10834)
+++ trunk/FACT++/src/fadctrl.cc	(revision 10835)
@@ -1,3 +1,2 @@
-#include <boost/bind.hpp>
 #include <boost/bind.hpp>
 #include <boost/array.hpp>
@@ -11,4 +10,5 @@
 #include <boost/asio/error.hpp>
 #include <boost/asio/deadline_timer.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 
 #include "Dim.h"
@@ -18,5 +18,4 @@
 #include "Connection.h"
 #include "Configuration.h"
-#include "Timers.h"
 #include "Console.h"
 #include "Converter.h"
@@ -86,5 +85,11 @@
 
 private:
-    void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int/* type*/)
+    enum
+    {
+        kReadHeader = 1,
+        kReadData   = 2,
+    };
+
+    void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int type)
     {
         // Do not schedule a new read if the connection failed.
@@ -110,6 +115,15 @@
         // FIXME FIXME FIXME. The data block could have the same size!!!!!
         // !!!!!!!!!!!!!!!!!!!
-        if (bytes_received == sizeof(FAD::EventHeader))
-        {
+        if (type==kReadHeader)
+        {
+            if (bytes_received!=sizeof(FAD::EventHeader))
+            {
+                ostringstream str;
+                str << "Bytes received (" << bytes_received << " don't match header size " << sizeof(FAD::EventHeader);
+                Error(str);
+                PostClose(false);
+                return;
+            }
+
             fEventHeader = fBuffer;
 
@@ -132,5 +146,5 @@
 
             fBuffer.resize(fEventHeader.fPackageLength-sizeof(FAD::EventHeader)/2);
-            AsyncRead(ba::buffer(fBuffer));
+            AsyncRead(ba::buffer(fBuffer), kReadData);
             AsyncWait(fInTimeout, 50, &Connection::HandleReadTimeout);
 
@@ -201,5 +215,5 @@
 
         fBuffer.resize(sizeof(FAD::EventHeader)/2);
-        AsyncRead(ba::buffer(fBuffer));
+        AsyncRead(ba::buffer(fBuffer), kReadHeader);
     }
 
@@ -248,5 +262,5 @@
 
         fBuffer.resize(sizeof(FAD::EventHeader)/2);
-        AsyncRead(ba::buffer(fBuffer));
+        AsyncRead(ba::buffer(fBuffer), kReadHeader);
 
 //        for (int i=0; i<36; i++)
@@ -262,4 +276,5 @@
         msg << "Sending command:" << hex;
         msg << " 0x" << setw(4) << setfill('0') << cmd[0];
+        msg << " (+ " << cmd.size()-1 << " bytes data)";
         Message(msg);
 
@@ -296,6 +311,10 @@
     Connection(ioservice, imp()),
     fIsVerbose(true), fIsHexOutput(false), fIsDataOutput(false), fCounter(0)
-
-    {
+    {
+        // Maximum possible needed space:
+        // The full header, all channels with all DRS bins
+        // Two trailing shorts
+        fBuffer.reserve(sizeof(FAD::EventHeader) + FAD::kNumChannels*(sizeof(FAD::ChannelHeader) + FAD::kMaxBins*sizeof(uint16_t)) + 2*sizeof(uint16_t));
+
         SetLogStream(&imp);
     }
@@ -500,151 +519,6 @@
 */
 // ------------------------------------------------------------------------
-extern "C"
-{
-    extern void *readFAD(void*);
-    extern void *procEvt(void*);
-    extern void *writeEvt(void*);
-    extern void initReadFAD();
-};
-
-#include "EventBuilder.h"
-
-class EventBuilderWrapper
-{
-public:
-    // FIXME
-    static EventBuilderWrapper *This;
-
-private:
-    boost::thread fThread;
-
-    enum CommandStates_t // g_runStat
-    {
-        kAbort      = -2,  // quit as soon as possible ('abort')
-        kExit       = -1,  // stop reading, quit when buffered events done ('exit')
-        kInitialize =  0,  // 'initialize' (e.g. dim not yet started)
-        kHybernate  =  1,  // do nothing for long time ('hybernate') [wakeup within ~1sec]
-        kSleep      =  2,  // do nothing ('sleep')                   [wakeup within ~10msec]
-        kModeFlush  = 10,  // read data from camera, but skip them ('flush')
-        kModeTest   = 20,  // read data and process them, but do not write to disk ('test')
-        kModeFlag   = 30,  // read data, process and write all to disk ('flag')
-        kModeRun    = 40,  // read data, process and write selected to disk ('run')
-    };
-
-    MessageImp &fMsg;
-
-public:
-    EventBuilderWrapper(MessageImp &msg) : fMsg(msg)
-    {
-        if (This)
-            throw runtime_error("EventBuilderWrapper cannot be instantiated twice.");
-
-        This = this;
-        Start();
-    }
-
-    void Update(ostringstream &out, int severity)
-    {
-        fMsg.Update(out, severity);
-    }
-
-    void Start()
-    {
-        if (fThread.joinable())
-        {
-            fMsg.Warn("Start - EventBuilder still running");
-            return;
-        }
-
-        fMsg.Message("Initializing EventBuilder");
-        initReadFAD();
-
-        g_runStat = kHybernate;
-        fThread = boost::thread(readFAD, (void*)NULL);
-
-        fMsg.Message("EventBuilder started");
-    }
-    void Abort()
-    {
-        fMsg.Message("Waiting for EventBuilder to abort...");
-        g_runStat = kAbort;
-        fThread.join();
-        fMsg.Message("EventBuilder stopped.");
-    }
-
-    void Exit()
-    {
-        fMsg.Message("Waiting for EventBuilder to exit - be patient...");
-        g_runStat = kExit;
-    }
-
-    void Wait()
-    {
-        fThread.join();
-        fMsg.Message("EventBuilder stopped.");
-    }
-
-    void Hybernate() { g_runStat = kHybernate; }
-    void Sleep()     { g_runStat = kSleep;     }
-    void FlushMode() { g_runStat = kModeFlush; }
-    void TestMode()  { g_runStat = kModeTest;  }
-    void FlagMode()  { g_runStat = kModeFlag;  }
-    void RunMode()   { g_runStat = kModeRun;   }
-
-    // FIXME: To be removed
-    void SetMode(int mode) { g_runStat = mode; }
-
-    bool IsConnected(int i) const     { return gi_NumConnect[i]==7; }
-    bool IsDisconnected(int i) const  { return gi_NumConnect[i]==0; }
-    int  GetNumConnected(int i) const { return gi_NumConnect[i]; }
-
-    void Restart()
-    {
-        Abort();
-        Start();
-    }
-
-    ~EventBuilderWrapper()
-    {
-        Abort();
-    }
-};
-/*
-extern "C" {
-
-void Error(int severity, int errnum, const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-
-    int n=256;
-
-    char *ret=0;
-    while (1)
-    {
-        ret = new char[n+1];
-
-        const int sz = vsnprintf(ret, n, fmt, ap);
-        if (sz<=n)
-            break;
-
-        n *= 2;
-        delete [] ret;
-    };
-
-    va_end(ap);
-
-    ostringstream str;
-    str << ret << " (" << errnum << ":" << strerror(errnum) << ")";
-
-    delete [] ret;
-
-    EventBuilderWrapper::This->Update(str, severity);
-}
-
-}
-*/
-
-EventBuilderWrapper *EventBuilderWrapper::This = 0;
+
+#include "EventBuilderWrapper.h"
 
 // ------------------------------------------------------------------------
@@ -943,5 +817,5 @@
             }
 
-            T::Message(str.str());
+            T::Out() << str.str() << endl;
         }
 
@@ -1000,7 +874,9 @@
     int Connect()
     {
-        T::Error("FIXME - Propagate IP Addresses to EventBuilder");
-
-        Start();
+        vector<string> addr;
+        for (BoardList::iterator i=fBoards.begin(); i!=fBoards.end(); i++)
+            addr.push_back(i->second.first);
+
+        Start(addr);
         EnableAll(true);
 
@@ -1126,5 +1002,5 @@
 
         if (nconnected1==0 && nconnected2==0)
-            return FAD::kDisconnected;
+            return IsThreadRunning() ? FAD::kOffline : FAD::kDisconnected;
 
         // FIXME: Evaluate event builder status
@@ -1170,6 +1046,9 @@
 
         // State names
+        T::AddStateName(FAD::kDisconnected, "Offline",
+                        "All enabled FAD boards are disconnected and the event-builer thread is not running.");
+
         T::AddStateName(FAD::kDisconnected, "Disconnected",
-                        "All enabled FAD boards are disconnected.");
+                        "All enabled FAD boards are disconnected, but the event-builder thread is running.");
 
         T::AddStateName(FAD::kConnected, "Connected",
@@ -1269,9 +1148,9 @@
             ("");*/
 
-        T::AddEvent("CONNECT", FAD::kDisconnected)
+        T::AddEvent("CONNECT", FAD::kOffline)
             (boost::bind(&StateMachineFAD::Connect, this))
             ("");
 
-        T::AddEvent("DISCONNECT")
+        T::AddEvent("DISCONNECT", FAD::kDisconnected, FAD::kConnecting, FAD::kConnected)
             (boost::bind(&StateMachineFAD::Disconnect, this))
             ("");
@@ -1281,9 +1160,9 @@
             ("");
 
-        T::AddEvent("ADD_ADDRESS", "C", FAD::kDisconnected)
+        T::AddEvent("ADD_ADDRESS", "C", FAD::kOffline)
             (boost::bind(&StateMachineFAD::AddAddress, this, _1))
             ("Add the address of a DRS4 board to the first free slot"
              "|IP[string]:address in the format <address:port>");
-        T::AddEvent("REMOVE_SLOT", "S:1", FAD::kDisconnected)
+        T::AddEvent("REMOVE_SLOT", "S:1", FAD::kOffline)
             (boost::bind(&StateMachineFAD::RemoveSlot, this, _1))
             ("Remove the Iaddress in slot n. For a list see LIST"
@@ -1307,4 +1186,6 @@
         fIsDataOutput = conf.Get<bool>("data-out");
 
+        SetMaxMemory(conf.Get<unsigned int>("max-mem"));
+
         if (!(conf.Has("base-addr") ^ conf.Has("addr")))
         {
@@ -1371,5 +1252,5 @@
         }
 
-        EnableAll();
+        Connect();
 
         return true;
@@ -1471,6 +1352,7 @@
         ("hex-out",    po_bool(),  "Enable printing contents of all printed messages also as hex data.")
         ("data-out",   po_bool(),  "Enable printing received event data.")
-        ("addr",       vars<string>(), "Network address of FAD")
-        ("base-addr",  var<string>(),  "Base address of all FAD")
+        ("addr",       vars<string>(),     "Network address of FAD")
+        ("base-addr",  var<string>(),      "Base address of all FAD")
+        ("max-mem,m",  var<unsigned int>(100), "Maximum memory the event builder thread is allowed to consume for its event buffer")
         ;
 
