Index: /trunk/FACT++/src/fscctrl.cc
===================================================================
--- /trunk/FACT++/src/fscctrl.cc	(revision 17635)
+++ /trunk/FACT++/src/fscctrl.cc	(revision 17636)
@@ -28,12 +28,10 @@
 class ConnectionFSC : public Connection
 {
-    boost::array<unsigned char, 4096> fArray;
-    vector<unsigned char> input_buffer;
-    boost::array<unsigned char, sizeof(FSC::BinaryOutput_t)> one_message;
+    FSC::BinaryOutput_t fMsg;       // A single message
 
     bool fIsVerbose;
-    bool fDump;
-
-    ofstream fDumpStream;
+
+    size_t fNumConsecutiveErrors;   // Number of consecutive messages with errors
+    size_t fNumConsecutiveMessages; // Number of consecutive message which are ok
 
 
@@ -56,35 +54,4 @@
     virtual void UpdateCur(float, const vector<float>&) 
     {
-    }
-
-    /*
-    virtual void UpdateError()
-    {
-        if (!fIsVerbose)
-            return;
-
-        Out() << endl << kRed << "Error received:" << endl;
-        Out() << fError;
-        if (fIsHexOutput)
-            Out() << Converter::GetHex<uint16_t>(fError, 16) << endl;
-    }
-*/
-
-    void Dump(const string &str) 
-    {
-        if (!fDumpStream.is_open()) 
-        {
-            fDumpStream.open("socket_dump-fsc.txt", ios::app);
-            if (!fDumpStream) 
-            {
-                //ostringstream str;
-                //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";
-                //Error(str);
-
-                return;
-            }
-        }
-
-        fDumpStream << str << endl;
     }
 
@@ -107,7 +74,13 @@
     }
 
-    uint16_t fletcher16( uint8_t const *data, size_t bytes ) 
-    {
-        uint16_t sum1 = 0xff, sum2 = 0xff;
+    template<typename T>
+    uint16_t fletcher16(const T *t, size_t cnt)
+    {
+        const uint8_t *data = reinterpret_cast<const uint8_t*>(t);
+
+        size_t bytes = cnt*sizeof(T);
+
+        uint16_t sum1 = 0xff;
+        uint16_t sum2 = 0xff;
 
         while (bytes) 
@@ -115,82 +88,91 @@
             size_t tlen = bytes > 20 ? 20 : bytes;
             bytes -= tlen;
+
             do {
-                    sum2 += sum1 += *data++;
+                sum2 += sum1 += *data++;
             } while (--tlen);
+
             sum1 = (sum1 & 0xff) + (sum1 >> 8);
             sum2 = (sum2 & 0xff) + (sum2 >> 8);
         }
-        /* Second reduction step to reduce sums to 8 bits */
+
+        // Second reduction step to reduce sums to 8 bits
         sum1 = (sum1 & 0xff) + (sum1 >> 8);
         sum2 = (sum2 & 0xff) + (sum2 >> 8);
+
         return sum2 << 8 | sum1;
     }
-    
-    /* ProcessMessage is only called from HandleRead, when enough bytes were received from the FSC
-     * The bytes of one message were already stored in *one_message*.
-     * We convert it to an instance of FSC::BinaryOutput_t 
-     * then we check the two checksums
-     * and then update the DimServices or not depending on the checksums
-     */
-    void ProcessMessage() {
-
-        FSC::BinaryOutput_t* bin_out;
-        bin_out = (FSC::BinaryOutput_t*)one_message.data();
-        
-        if (fIsVerbose) {
+
+    bool CheckChecksum()
+    {
+        const uint16_t volt_checksum = fletcher16(fMsg.adc_values,    kNumVoltageChannels);
+        const uint16_t resi_checksum = fletcher16(fMsg.ad7719_values, kNumResistanceChannels);
+
+        const bool volt_ok = volt_checksum == fMsg.adc_values_checksum;
+        const bool resi_ok = resi_checksum == fMsg.ad7719_values_checksum;
+
+        if (volt_ok && resi_ok)
+            return true;
+
+        fNumConsecutiveErrors++;
+
+        ostringstream out;
+        out << "Checksum error (V:";
+        out << hex << setfill('0');
+
+        if (volt_ok)
+            out << "----|----";
+        else
+        {
+            out << setw(4) << volt_checksum;
+            out << "|";
+            out << setw(4) << fMsg.adc_values_checksum;
+        }
+
+        out << ", R:";
+
+        if (resi_ok)
+            out << "----|----";
+        else
+        {
+            out << setw(4) << resi_checksum;
+            out << "|";
+            out << setw(4) << fMsg.ad7719_values_checksum;
+        }
+
+        out << ",  " << dec;
+        out << "Nok=" << fNumConsecutiveMessages << ", ";
+        out << "Nerr=" << fNumConsecutiveErrors << ")";
+
+        Warn(out);
+
+        fNumConsecutiveMessages = 0;
+
+        return false;
+    }
+
+    void ProcessMessage()
+    {
+        if (fIsVerbose)
            Out() << "Received one_message of FSC::BinaryOutput_t ... will now process it" << endl;
-        }
-        
-        
-        uint16_t volt_checksum = fletcher16( (uint8_t const *)&one_message[offsetof(FSC::BinaryOutput_t,adc_values)], 
-                                                sizeof(bin_out->adc_values) );
-        if (volt_checksum != bin_out->adc_values_checksum ){
-            ostringstream out;
-            out << "volt checksums are different. We calculated " << volt_checksum << " transmitted was: ";
-            out << bin_out->adc_values_checksum << ".";
-            Warn(out);
-            StartRead();
+
+        if (!CheckChecksum())
             return;
-        }
-        
-        uint16_t resist_checksum = fletcher16( (uint8_t const *)&one_message[offsetof(FSC::BinaryOutput_t,ad7719_values)], 
-                                                sizeof(bin_out->ad7719_values) );
-        if (resist_checksum != bin_out->ad7719_values_checksum ){
-            ostringstream out;
-            out << "resist checksums are different. We calculated " << resist_checksum << " transmitted was: ";
-            out << bin_out->ad7719_values_checksum << ".";
-            Warn(out);
-            StartRead();
-            return;
-        }
-
-        vector<int> volt (bin_out->adc_values, 
-                            bin_out->adc_values + sizeof(bin_out->adc_values) / sizeof(uint16_t) 
-                          );
-                          
-        vector<float> resist(bin_out->ad7719_values, 
-                            bin_out->ad7719_values + sizeof(bin_out->ad7719_values) / sizeof(uint32_t) 
-                          );
-        float time= float(bin_out->time_sec) + float(bin_out->time_ms)/1000.;
-
-        if (volt.size()!=84 || resist.size()!=64) {
-            ostringstream out;
-
-            out << "Something went wrong in vector constructors " << volt.size() << " voltages and ";
-            out << resist.size() << " resistances received; 84 and 64 expected)";
-            Warn(out);
-            StartRead();
-            return;
-        }
-        
+
+        // That looks a bit odd because it copies the values twice for no reason.
+        // This is historical and keeps the following code consistent with the
+        // previous code which was reading ascii data from the fsc
+        vector<float> volt(  fMsg.adc_values,    fMsg.adc_values    + kNumVoltageChannels);
+        vector<float> resist(fMsg.ad7719_values, fMsg.ad7719_values + kNumResistanceChannels);
+
+        const float time = fMsg.time_sec + fMsg.time_ms/1000.;
+
         // We want to convert the pure ADC values from the FSC board to mV and kOhm respectively
         // So we do:
-        for (unsigned int i=0; i<volt.size(); i++){
+        for (unsigned int i=0; i<volt.size(); i++)
             volt[i] /= 10;
-        }
-        for (unsigned int i=0; i<resist.size(); i++){
+
+        for (unsigned int i=0; i<resist.size(); i++)
             resist[i] *= (6.25 * 1024) / (1 << 25);
-        }
-        
 
         int mapv[] =
@@ -208,5 +190,4 @@
             -1
         };
-
 
         int mapc[] =
@@ -487,26 +468,25 @@
         UpdateCur( time, currents);
         UpdateHum( time, humidities);
-        
-    }
-
-    void StartRead() {
-        // DN: 20140318
-        async_read_some(ba::buffer(fArray),
-                            boost::bind(&ConnectionFSC::HandleRead, this,     
-                            dummy::error, 
-                            dummy::bytes_transferred)
-                        );
-        
-        // FIXME: Add timeout here
-    }
-    
-    void HandleRead(const boost::system::error_code& err, size_t bytes_received) {
+
+        fNumConsecutiveErrors = 0;
+        fNumConsecutiveMessages++;
+    }
+
+    void StartRead()
+    {
+        ba::async_read(*this, ba::buffer(&fMsg, sizeof(FSC::BinaryOutput_t)),
+                       boost::bind(&ConnectionFSC::HandleRead, this,
+                                   dummy::error, dummy::bytes_transferred));
+
+        AsyncWait(fInTimeout, 35000, &Connection::HandleReadTimeout); // 30s
+    }
+
+    void HandleRead(const boost::system::error_code& err, size_t bytes_received)
+    {
         // Do not schedule a new read if the connection failed.
         if (bytes_received==0 || err)
         {
             if (err==ba::error::eof)
-            {
                 return;
-            }
 
             // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
@@ -523,22 +503,17 @@
             return;
         }
-        
-        input_buffer.insert(input_buffer.end(), fArray.data(), fArray.data()+bytes_received);
-        if (input_buffer.size() >= sizeof(FSC::BinaryOutput_t)){
-            for (unsigned int i=0; i<sizeof(FSC::BinaryOutput_t); i++){
-                one_message[i] = input_buffer[i];
-            }
-            input_buffer.erase(input_buffer.begin(),input_buffer.begin()+sizeof(FSC::BinaryOutput_t));
-            ProcessMessage();
-        }
-
+
+        ProcessMessage();
         StartRead();
     }
 
-    void ConnectionEstablished() {
+    void ConnectionEstablished()
+    {
+        fNumConsecutiveErrors   = 0;
+        fNumConsecutiveMessages = 0;
+
         StartRead();
     }
 
-/*
     void HandleReadTimeout(const bs::error_code &error)
     {
@@ -575,9 +550,8 @@
         PostClose();
     }
-*/
 
 public:
     ConnectionFSC(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()),
-        fIsVerbose(false), fDump(false)
+        fIsVerbose(false)
     {
         SetLogStream(&imp);
@@ -587,9 +561,4 @@
     {
         fIsVerbose = b;
-    }
-
-    void SetDumpStream(bool b)
-    {
-        fDump = b;
     }
 
@@ -837,14 +806,4 @@
     }
 
-    int SetDumpStream(const EventImp &evt)
-    {
-        if (!CheckEventSize(evt.GetSize(), "SetDumpStream", 1))
-            return T::kSM_FatalError;
-
-        fFSC.SetDumpStream(evt.GetBool());
-
-        return T::GetCurrentState();
-    }
-
 public:
     StateMachineFSC(ostream &out=cout) :
@@ -863,9 +822,4 @@
             ("set verbosity state"
              "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
-
-        T::AddEvent("DUMP_STREAM", "B:1")
-            (bind(&StateMachineFSC::SetDumpStream, this, placeholders::_1))
-            (""
-             "");
 
         // Conenction commands
