Index: trunk/FACT++/src/fscctrl.cc
===================================================================
--- trunk/FACT++/src/fscctrl.cc	(revision 17540)
+++ trunk/FACT++/src/fscctrl.cc	(revision 17623)
@@ -28,5 +28,7 @@
 class ConnectionFSC : public Connection
 {
-    boost::asio::streambuf fBuffer;
+    boost::array<unsigned char, 4096> fArray;
+    vector<unsigned char> input_buffer;
+    boost::array<unsigned char, sizeof(FSC::BinaryOutput_t)> one_message;
 
     bool fIsVerbose;
@@ -44,13 +46,13 @@
     }
 
-    virtual void UpdateHum(float, const vector<float>&)
-    {
-    }
-
-    virtual void UpdateVolt(float, const vector<float>&)
-    {
-    }
-
-    virtual void UpdateCur(float, const vector<float>&)
+    virtual void UpdateHum(float, const vector<float>&) 
+    {
+    }
+
+    virtual void UpdateVolt(float, const vector<float>&) 
+    {
+    }
+
+    virtual void UpdateCur(float, const vector<float>&) 
     {
     }
@@ -69,10 +71,10 @@
 */
 
-    void Dump(const string &str)
-    {
-	if (!fDumpStream.is_open())
-	{
-	    fDumpStream.open("socket_dump-fsc.txt", ios::app);
-            if (!fDumpStream)
+    void Dump(const string &str) 
+    {
+        if (!fDumpStream.is_open()) 
+        {
+            fDumpStream.open("socket_dump-fsc.txt", ios::app);
+            if (!fDumpStream) 
             {
                 //ostringstream str;
@@ -91,5 +93,5 @@
     // From: http://de.wikipedia.org/wiki/Pt100
     //
-    double GetTempPT1000(double R) const
+    double GetTempPT1000(double R) const 
     {
         // This is precise within the range 5degC and 25degC
@@ -105,160 +107,75 @@
     }
 
-
-    void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int /*type*/)
-    {
-        // Do not schedule a new read if the connection failed.
-        if (bytes_received==0 || err)
-        {
-            if (err==ba::error::eof)
-                Warn("Connection closed by remote host (FSC).");
-
-            // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
-            // 125: Operation canceled
-            if (err && err!=ba::error::eof &&                     // Connection closed by remote host
-                err!=ba::error::basic_errors::not_connected &&    // Connection closed by remote host
-                err!=ba::error::basic_errors::operation_aborted)  // Connection closed by us
-            {
-                ostringstream str;
-                str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
-                Error(str);
-            }
-            PostClose(err!=ba::error::basic_errors::operation_aborted);
-            return;
-        }
-
-        if (fIsVerbose)
-           Out() << kBold << "Received (" << bytes_received << " bytes):" << endl;
-
-        /*
-         "status: 00000538 \n"
-         "time_s: 764.755 \n"
-         "VOLTAGES \n"
-         " \n"
-         "enable:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111  00001111 \n"
-         "  done:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111  00001111 \n"
-         "values:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 \n"
-         "RESISTANCES \n"
-         " \n"
-         "enable:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 \n"
-         "  done:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 \n"
-         "values: \n"
-         "1000.16 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         "1197.07 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         " 558.59  677.92  817.26  989.39 1200.35 1503.06 1799.90 2204.18 \n"
-         "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
-         "end.\n";
-         */
-/*
-        const unsigned int TIME_OFF = 3;
-        const unsigned int VOLT_OFF = 30;
-        const unsigned int CURR_OFF = 70;
-        const unsigned int HUMI_OFF = 110;
-        const unsigned int TEMP_OFF = 134;
-	*/
-
-	if (fDump)
-	{
-	    ostringstream msg;
-	    msg << "--- " << Time().GetAsStr() << " --- received " << bytes_received << " bytes.";
-            Dump(msg.str());
-	}
-
-
-        istream is(&fBuffer);
-
-        int state = 0;
-        bool values = false;
-
-        vector<int>   volt;
-        vector<float> resist;
-//        int status=-1;
-        float time=0;
-
-        string buffer;
-        while (getline(is, buffer, '\n'))
-        {
-            if (fIsVerbose)
-                Out() << buffer << endl;
-	    if (fDump)
-                Dump(buffer);
-
-            buffer = Tools::Trim(buffer);
-
-            if (buffer.empty())
-                continue;
-
-            if (buffer.substr(0, 4)=="end.")
-                break;
-
-            if (buffer.substr(0, 8)=="status: ")
-            {
-//                status = stoi(buffer.substr(8));
-                continue;
-            }
-
-            if (buffer.substr(0, 8)=="time_s: ")
-            {
-                time = stof(buffer.substr(8));
-                continue;
-            }
-
-            if (buffer.substr(0, 8)=="VOLTAGES")
-            {
-                state = 1;
-                continue;
-            }
-
-            if (buffer.substr(0, 11)=="RESISTANCES")
-            {
-                state = 2;
-                continue;
-            }
-
-            if (state==1 && buffer.substr(0, 7)=="values:")
-            {
-                istringstream in(buffer.substr(7));
-                while (1)
-                {
-                    int v;
-                    in >> v;
-                    if (!in)
-                        break;
-
-                    volt.push_back(v);
-                }
-                continue;
-            }
-
-            if (state==2 && buffer.substr(0, 7)=="values:")
-            {
-                values = true;
-                continue;
-            }
-
-            if (state==2 && !values)
-                continue;
-
-            istringstream in(buffer);
-            while (1)
-            {
-                float f;
-                in >> f;
-                if (!in)
-                    break;
-
-                resist.push_back(f);
-            }
-        }
-
-        if (volt.size()!=84 || resist.size()!=64)
-        {
+    uint16_t fletcher16( uint8_t const *data, size_t bytes ) 
+    {
+        uint16_t sum1 = 0xff, sum2 = 0xff;
+
+        while (bytes) 
+        {
+            size_t tlen = bytes > 20 ? 20 : bytes;
+            bytes -= tlen;
+            do {
+                    sum2 += sum1 += *data++;
+            } while (--tlen);
+            sum1 = (sum1 & 0xff) + (sum1 >> 8);
+            sum2 = (sum2 & 0xff) + (sum2 >> 8);
+        }
+        /* 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) {
+           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 << "Corrupted data received (" << volt.size() << " voltages and ";
+            out << "volt checksums are different. We calculated " << volt_checksum << " transmitted was: ";
+            out << bin_out->adc_values_checksum << ".";
+            Warn(out);
+            StartRead();
+            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);
@@ -266,4 +183,14 @@
             return;
         }
+        
+        // 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++){
+            volt[i] /= 10;
+        }
+        for (unsigned int i=0; i<resist.size(); i++){
+            resist[i] *= (6.25 * 1024) / (1 << 25);
+        }
+        
 
         int mapv[] =
@@ -560,23 +487,54 @@
         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) {
+        // 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))
+            // 125: Operation canceled
+            if (err && err!=ba::error::eof &&                     // Connection closed by remote host
+                err!=ba::error::basic_errors::not_connected &&    // Connection closed by remote host
+                err!=ba::error::basic_errors::operation_aborted)  // Connection closed by us
+            {
+                ostringstream str;
+                str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
+                Error(str);
+            }
+            PostClose(err!=ba::error::basic_errors::operation_aborted);
+            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();
+        }
 
         StartRead();
     }
 
-    void StartRead()
-    {
-        ba::async_read_until(*this, fBuffer, "end.\n",
-                             boost::bind(&ConnectionFSC::HandleReceivedData, this,
-                                         dummy::error, dummy::bytes_transferred, 0));
-
-        // FIXME: Add timeout here
-    }
-
-    // This is called when a connection was established
-    void ConnectionEstablished()
-    {
-        PostMessage("m", 1);
-
-        fBuffer.prepare(10000);
+    void ConnectionEstablished() {
         StartRead();
     }
