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