packet_finder.cpp
Go to the documentation of this file.
00001 
00010 /*****************************************************************************
00011 ** Includes
00012 *****************************************************************************/
00013 
00014 #include "../../include/kobuki_driver/packet_handler/packet_finder.hpp"
00015 
00016 /*****************************************************************************
00017 ** Namespaces
00018 *****************************************************************************/
00019 
00020 namespace kobuki {
00021 
00022 /*****************************************************************************
00023 ** Implementation
00024 *****************************************************************************/
00025 
00026 PacketFinderBase::PacketFinderBase() :
00027     state(waitingForStx), verbose(false)
00028 {
00029 }
00030 
00031 
00032 /*****************************************************************************
00033 ** Public
00034 *****************************************************************************/
00035 
00036 void PacketFinderBase::configure(const std::string &sigslots_namespace,
00037                const BufferType & putStx, const BufferType & putEtx, unsigned int sizeLengthField,
00038                unsigned int sizeMaxPayload, unsigned int sizeChecksumField, bool variableSizePayload)
00039 {
00040   size_stx = putStx.size();
00041   size_etx = putEtx.size();
00042   size_length_field = sizeLengthField;
00043   variable_size_payload = variableSizePayload;
00044   size_max_payload = sizeMaxPayload;
00045   size_payload = variable_size_payload ? 0 : sizeMaxPayload;
00046   size_checksum_field = sizeChecksumField;
00047   STX = putStx;
00048   ETX = putEtx;
00049   buffer = BufferType(size_stx + size_length_field + size_max_payload + size_checksum_field + size_etx);
00050   state = waitingForStx;
00051 
00052   sig_warn.connect(sigslots_namespace + std::string("/ros_warn"));
00053   sig_error.connect(sigslots_namespace + std::string("/ros_error"));
00054 
00055   //todo; exception
00056   // Problem1: size_length_field = 1, vairable_size_payload = false
00057 
00058   clear();
00059 }
00060 
00061 void PacketFinderBase::clear()
00062 {
00063   state = waitingForStx;
00064   buffer.clear();
00065 }
00066 
00067 void PacketFinderBase::enableVerbose()
00068 {
00069   verbose = true;
00070 }
00071 
00072 bool PacketFinderBase::checkSum()
00073 {
00074   return true;
00075 }
00076 
00077 unsigned int PacketFinderBase::numberOfDataToRead()
00078 {
00079   unsigned int num(0);
00080 
00081   switch (state)
00082   {
00083     case waitingForEtx:
00084       num = 1;
00085       break;
00086 
00087     case waitingForPayloadToEtx:
00088       num = size_payload + size_etx + size_checksum_field;
00089       break;
00090 
00091     case waitingForPayloadSize:
00092       num = size_checksum_field;
00093       break;
00094 
00095     case waitingForStx:
00096     case clearBuffer:
00097     default:
00098       num = 1;
00099       break;
00100   }
00101 
00102   if (verbose)
00103   {
00104     printf("[state(%d):%02d]", state, num);
00105   }
00106   return num;
00107 }
00108 
00109 void PacketFinderBase::getBuffer(BufferType & bufferRef)
00110 {
00111   bufferRef = buffer;
00112 }
00113 
00121 bool PacketFinderBase::update(const unsigned char * incoming, unsigned int numberOfIncoming)
00122 {
00123   // clearBuffer = 0, waitingForStx, waitingForPayloadSize, waitingForPayloadToEtx, waitingForEtx,
00124   // std::cout << "update [" << numberOfIncoming << "][" << state << "]" << std::endl;
00125   if (!(numberOfIncoming > 0))
00126     return false;
00127 
00128   bool found_packet(false);
00129 
00130   if ( state == clearBuffer ) {
00131     buffer.clear();
00132     state = waitingForStx;
00133   }
00134   switch (state)
00135   {
00136     case waitingForStx:
00137       if (WaitForStx(incoming[0]))
00138       {
00139         if (size_length_field)
00140         {
00141           state = waitingForPayloadSize; // kobukibot
00142         }
00143         else
00144         {
00145           if (variable_size_payload)
00146           {
00147             // e.g. stargazer
00148             state = waitingForEtx;
00149           }
00150           else
00151           {
00152             // e.g. iroboQ
00153             //Todo; should put correct state
00154             state = waitingForPayloadToEtx;
00155           }
00156         }
00157       }
00158       break;
00159     case waitingForEtx:
00160       if (waitForEtx(incoming[0], found_packet))
00161       {
00162         state = clearBuffer;
00163       }
00164       break;
00165 
00166     case waitingForPayloadSize:
00167       if (waitForPayloadSize(incoming, numberOfIncoming))
00168       {
00169         state = waitingForPayloadToEtx;
00170       }
00171       break;
00172 
00173     case waitingForPayloadToEtx:
00174       if (waitForPayloadAndEtx(incoming, numberOfIncoming, found_packet))
00175       {
00176         state = clearBuffer;
00177       }
00178       break;
00179 
00180     default:
00181       state = waitingForStx;
00182       break;
00183   }
00184   if ( found_packet ) {
00185     return checkSum();  //what happen if checksum is equal to false(== -1)?
00186   } else {
00187     return false;
00188   }
00189 }
00190 /*****************************************************************************
00191 ** Protected
00192 *****************************************************************************/
00193 
00194 bool PacketFinderBase::WaitForStx(const unsigned char datum)
00195 {
00196   bool found_stx(true);
00197 
00198   // add incoming datum
00199   buffer.push_back(datum);
00200 
00201   // check whether we have STX
00202   for (unsigned int i = 0; i < buffer.size() && i < STX.size(); i++)
00203   {
00204     if (buffer[i] != STX[i])
00205     {
00206       found_stx = false;
00207       buffer.pop_front();
00208       break;
00209     }
00210   }
00211 
00212   return (found_stx && buffer.size() == STX.size());
00213 }
00214 
00215 bool PacketFinderBase::waitForPayloadSize(const unsigned char * incoming, unsigned int numberOfIncoming)
00216 {
00217   // push data
00218   unsigned char first_byte;
00219   for (unsigned int i = 0; i < numberOfIncoming; i++) {
00220     first_byte = incoming[i];
00221     buffer.push_back(incoming[i]);
00222   }
00223 
00224   if (verbose)
00225   {
00226     for (unsigned int i = 0; i < buffer.size(); i++)
00227       printf("%02x ", buffer[i]);
00228     printf("\n");
00229   }
00230 
00231   // check when we need to wait for etx
00232   if (buffer.size() < size_stx + size_length_field)
00233   {
00234     return false;
00235   }
00236   else
00237   {
00238     switch (size_length_field)
00239     {
00240       case 1: // kobuki
00241         size_payload = buffer[size_stx];
00242         break;
00243       case 2:
00244         size_payload = buffer[size_stx];
00245         size_payload |= buffer[size_stx + 1] << 8;
00246         break;
00247       case 4:
00248         size_payload = buffer[size_stx];
00249         size_payload |= buffer[size_stx + 1] << 8;
00250         size_payload |= buffer[size_stx + 2] << 16;
00251         size_payload |= buffer[size_stx + 3] << 24;
00252         break;
00253       default:
00254         // put assertion failure
00255         size_payload = 1;
00256         break;
00257     }
00258 
00259     if (verbose)
00260     {
00261       printf("[payloadSize: %d]\n", size_payload);
00262     }
00263 
00264     return true;
00265   }
00266 }
00267 
00268 bool PacketFinderBase::waitForEtx(const unsigned char incoming, bool & foundPacket)
00269 {
00270   // push data
00271   buffer.push_back(incoming);
00272 
00273   // check when we need to wait for etx
00274   // if minimum payload size is 1
00275   if (buffer.size() < size_stx + size_etx + 1)
00276   {
00277     return false;
00278   }
00279   else
00280   {
00281     unsigned int number_of_match(0);
00282     for (unsigned int i = 0; i < ETX.size(); i++)
00283     {
00284       if (buffer[buffer.size() - ETX.size() + i] == ETX[i])
00285       {
00286         number_of_match++;
00287       }
00288     }
00289 
00290     if (number_of_match == ETX.size())
00291     {
00292       foundPacket = true;
00293       return true;
00294     }
00295 
00296     if (buffer.size() >= size_stx + size_max_payload + size_etx)
00297       return true;
00298     else
00299       return false;
00300   }
00301 }
00302 
00303 bool PacketFinderBase::waitForPayloadAndEtx(const unsigned char * incoming, unsigned int numberOfIncoming, bool & foundPacket)
00304 {
00305   // push data
00306   for (unsigned int i = 0; i < numberOfIncoming; i++)
00307   {
00308     buffer.push_back(incoming[i]);
00309   }
00310   /*********************
00311   ** Error Handling
00312   **********************/
00313   if ( size_payload > size_max_payload ) {
00314     state = clearBuffer;
00315     std::ostringstream ostream;
00316     ostream << "abnormally sized payload retrieved, clearing [" << size_max_payload << "][" << size_payload << "]";
00317 
00318     ostream << std::setfill('0') << std::uppercase; //declare once, use everytime
00319 //      ostream.fill('0') //call once, affects everytime
00320 //      ostream.width(2); //need to call everytime
00321 
00322 /*
00323     ostream << "[";
00324     for (unsigned int i = 0; i < numberOfIncoming; ++i ) {
00325       ostream.width(2); // need to declare evertime
00326       ostream << std::hex << static_cast<int>(*(incoming+i)) << " " << std::dec;
00327     }
00328     ostream << "\b]";
00329 */
00330     ostream << ", buffer: [" << std::setw(2) << buffer.size() << "][";
00331     for (unsigned int i = 0; i < buffer.size(); ++i ) {
00332       ostream << std::setw(2) << std::hex << static_cast<int>(buffer[i]) << " " << std::dec;
00333     }
00334     ostream << "\b]";
00335 
00336     sig_error.emit(ostream.str());
00337     return false;
00338   }
00339   // check when we need to wait for etx
00340   if (buffer.size() < size_stx + size_length_field + size_payload + size_checksum_field + size_etx)
00341   {
00342     return false;
00343   }
00344   else
00345   {
00346     if (verbose) {
00347       std::cout << "Start check etx " << std::endl;
00348       for (unsigned int i = 0; i < numberOfIncoming; ++i ) {
00349         std::cout << std::hex << static_cast<int>(*(incoming+i)) << " ";
00350       }
00351       std::cout << std::dec << std::endl;
00352     }
00353     foundPacket = true;
00354 
00355     for (unsigned int i = (size_stx + size_length_field + size_payload + size_checksum_field);
00356         i < (size_stx + size_length_field + size_payload + size_checksum_field + size_etx); i++)
00357     {
00358       if (buffer[i] != ETX[i])
00359       {
00360         foundPacket = false;
00361       }
00362     }
00363     if (verbose)
00364       std::cout << "End of checking etx " << std::endl;
00365     return true;
00366   }
00367 }
00368 
00369 
00370 } // namespace kobuki


kobuki_driver
Author(s): Daniel Stonier , Younghun Ju , Jorge Santos Simon
autogenerated on Mon Oct 6 2014 01:31:10