SVHReceiveThread.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of the SCHUNK SVH Driver suite.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2014 SCHUNK Mobile Greifsysteme GmbH, Lauffen/Neckar Germany
00012 // © Copyright 2014 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00013 //
00014 // -- END LICENSE BLOCK ------------------------------------------------
00015 
00016 //----------------------------------------------------------------------
00029 //----------------------------------------------------------------------
00030 #include <driver_svh/SVHReceiveThread.h>
00031 #include <driver_svh/Logging.h>
00032 
00033 
00034 using icl_comm::ArrayBuilder;
00035 
00036 namespace driver_svh {
00037 
00038 SVHReceiveThread::SVHReceiveThread(const TimeSpan& period, boost::shared_ptr<Serial> device,
00039                                      ReceivedPacketCallback const & received_callback)
00040   : PeriodicThread("SVHReceiveThread", period),
00041     m_serial_device(device),
00042     m_received_state(eRS_HEADER1),
00043     m_length(0),
00044     m_data(0, 0),
00045     m_ab(0),
00046     m_packets_received(0),
00047     m_skipped_bytes(0),
00048     m_received_callback(received_callback)
00049 {}
00050 
00051 void SVHReceiveThread::run()
00052 {
00053   while (execute())
00054   {
00055     if (m_serial_device)// != NULL)
00056     {
00057       if (m_serial_device->IsOpen())
00058       {
00059         // All we every want to do is receiving data :)
00060         if(!receiveData())
00061         {
00062           waitPeriod();
00063         }
00064       }
00065       else
00066       {
00067         LOGGING_WARNING_C(DriverSVH, SVHReceiveThread, "Cannot read data from serial device. It is not opened!" << endl);
00068         waitPeriod();
00069       }
00070     }
00071 
00072     else
00073     {
00074     // Wait for the thread period so that the timing is in sync.
00075     waitPeriod();
00076   }
00077 }
00078 }
00079 
00080 bool SVHReceiveThread::receiveData()
00081 {
00082 
00083   /*
00084    * Each packet has to follow the defined packet structure which is ensured by the following state machine.
00085    * The "Bytestream" (not realy a stream) is interpreted byte by byte. If the structure is still right the
00086    * next state is entered, if a wrong byte is detected the whole packet is discarded and the SM switches to
00087    * the synchronization state aggain.
00088    * If the SM reaches the final state the packet will be given to the packet handler to decide what to do with
00089    * its content.
00090    *  NOTE: All layers working with a SerialPacket (except this one) assume that the packet has a valid structure
00091    *        and all data fields present.
00092    */
00093   uint8_t data_byte;
00094   int bytes = m_serial_device->Read(&data_byte, sizeof(uint8_t));
00095   if (bytes < 0)
00096   {
00097     LOGGING_TRACE_C(DriverSVH, SVHReceiveThread, "Serial read error:" << bytes << endl );
00098     return false;
00099   }
00100   if (bytes < 1)
00101   {
00102     return false;
00103   }
00104 
00105   switch (m_received_state)
00106   {
00107     case eRS_HEADER1:
00108     {
00109         if (data_byte == PACKET_HEADER1)
00110         {
00111           m_received_state = eRS_HEADER2;
00112         }
00113       else
00114       {
00115         m_skipped_bytes++;
00116       }
00117       break;
00118     }
00119     case eRS_HEADER2:
00120     {
00121         switch (data_byte)
00122         {
00123           case PACKET_HEADER2:
00124           {
00125             m_received_state = eRS_INDEX;
00126             break;
00127           }
00128           case PACKET_HEADER1:
00129           {
00130             m_received_state = eRS_HEADER2;
00131           m_skipped_bytes++;
00132             break;
00133           }
00134           default:
00135           {
00136             m_received_state = eRS_HEADER1;
00137           m_skipped_bytes+=2;
00138             break;
00139           }
00140         }
00141       break;
00142     }
00143     case eRS_INDEX:
00144     {
00145       // Reset Array Builder for each fresh packet
00146       m_ab.reset(0);
00147 
00148         // Data bytes are not cenverted in endianess at this point
00149       m_ab.appendWithoutConversion(data_byte);
00150         m_received_state = eRS_ADDRESS;
00151       break;
00152     }
00153     case eRS_ADDRESS:
00154     {
00155       //get the address
00156       m_ab.appendWithoutConversion(data_byte);
00157       m_received_state = eRS_LENGTH1;
00158       break;
00159     }
00160     case eRS_LENGTH1:
00161       {
00162       // get payload length
00163       m_ab.appendWithoutConversion(data_byte);
00164       m_received_state = eRS_LENGTH2;
00165       break;
00166     }
00167     case eRS_LENGTH2:
00168     {
00169       // get payload length
00170       m_ab.appendWithoutConversion(data_byte);
00171         m_length = m_ab.readBack<uint16_t>();
00172         m_received_state = eRS_DATA;
00173       m_data.clear();
00174       m_data.reserve(m_length);
00175       break;
00176     }
00177     case eRS_DATA:
00178     {
00179       // get the payload itself
00180       // Some conversion due to legacy hardware calls
00181       m_data.push_back(data_byte);
00182       m_ab.appendWithoutConversion(data_byte);
00183       if(m_data.size()>=m_length)
00184       {
00185         m_received_state = eRS_CHECKSUM1;
00186       }
00187       break;
00188     }
00189     case eRS_CHECKSUM1:
00190     {
00191       m_checksum1 = data_byte;
00192       m_checksum2 = 0;
00193       m_received_state = eRS_CHECKSUM2;
00194       break;
00195     }
00196     case eRS_CHECKSUM2:
00197       {
00198       m_checksum2=data_byte;
00199       uint8_t checksum1=m_checksum1;
00200       uint8_t checksum2=m_checksum2;
00201         // probe for correct checksum
00202         for (size_t i = 0; i < m_data.size(); ++i)
00203         {
00204           checksum1 -= m_data[i];
00205           checksum2 ^= m_data[i];
00206         }
00207 
00208         if ((checksum1 == 0) && (checksum2 == 0))
00209         {
00210       // start with an empty package
00211       // Warning: It is imperative for correct readouts to create the received_packet with the correct length!
00212       SVHSerialPacket received_packet(m_length);
00213       m_ab >> received_packet;
00214 
00215       m_packets_received++;
00216 
00217         if(m_skipped_bytes>0)LOGGING_TRACE_C(DriverSVH, SVHReceiveThread, "Skipped "<<m_skipped_bytes<<" bytes "<< endl);
00218         LOGGING_TRACE_C(DriverSVH, SVHReceiveThread, "Received packet index:" << received_packet.index <<", address:"<<received_packet.address<<", size:"<<received_packet.data.size() << endl);
00219         m_skipped_bytes=0;
00220       // notify whoever is waiting for this
00221       if (m_received_callback)
00222       {
00223         m_received_callback(received_packet, m_packets_received);
00224       }
00225 
00226       m_received_state = eRS_HEADER1;
00227       }
00228       else
00229       {
00230         m_received_state = eRS_HEADER1;
00231 
00232         SVHSerialPacket received_packet(m_length);
00233         m_ab >> received_packet;
00234 
00235         if(m_skipped_bytes>0)LOGGING_TRACE_C(DriverSVH, SVHReceiveThread, "Skipped "<<m_skipped_bytes<<" bytes: "<< endl);
00236         LOGGING_TRACE_C(DriverSVH, SVHReceiveThread, "Checksum error: "<< (int)checksum1<<","<<(int)checksum2<<"!=0, skipping "<<m_length+8<<"bytes, packet index:" << received_packet.index <<", address:"<<received_packet.address<<", size:"<<received_packet.data.size() << endl);
00237         m_skipped_bytes=0;
00238         if (m_received_callback)
00239         {
00240           m_received_callback(received_packet, m_packets_received);
00241         }
00242       }
00243       break;
00244     }
00245   }
00246 
00247   return true;
00248 }
00249 
00250 }


schunk_svh_driver
Author(s): Georg Heppner
autogenerated on Thu Jun 6 2019 18:29:08