Go to the documentation of this file.00001
00010
00011
00012
00013
00014 #include "../../include/kobuki_driver/packet_handler/packet_finder.hpp"
00015
00016
00017
00018
00019
00020 namespace kobuki {
00021
00022
00023
00024
00025
00026 PacketFinderBase::PacketFinderBase() :
00027 state(waitingForStx), verbose(false)
00028 {
00029 }
00030
00031
00032
00033
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
00056
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
00124
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;
00142 }
00143 else
00144 {
00145 if (variable_size_payload)
00146 {
00147
00148 state = waitingForEtx;
00149 }
00150 else
00151 {
00152
00153
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();
00186 } else {
00187 return false;
00188 }
00189 }
00190
00191
00192
00193
00194 bool PacketFinderBase::WaitForStx(const unsigned char datum)
00195 {
00196 bool found_stx(true);
00197
00198
00199 buffer.push_back(datum);
00200
00201
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
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
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:
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
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
00271 buffer.push_back(incoming);
00272
00273
00274
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
00306 for (unsigned int i = 0; i < numberOfIncoming; i++)
00307 {
00308 buffer.push_back(incoming[i]);
00309 }
00310
00311
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;
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
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
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 }