packet_finder.cpp
Go to the documentation of this file.
1 
10 /*****************************************************************************
11 ** Includes
12 *****************************************************************************/
13 
14 #include <sstream>
15 #include <fstream>
16 #include "../../include/xbot_driver/packet_handler/packet_finder.hpp"
17 using namespace std;
18 /*****************************************************************************
19 ** Namespaces
20 *****************************************************************************/
21 
22 namespace xbot {
23 
24 /*****************************************************************************
25 ** Implementation
26 *****************************************************************************/
27 
28 PacketFinderBase::PacketFinderBase() :
29  state(waitingForStx), verbose(false)
30 {
31 }
32 
33 
34 /*****************************************************************************
35 ** Public
36 *****************************************************************************/
37 
38 void PacketFinderBase::configure(const std::string &sigslots_namespace,
39  const BufferType & putStx, const BufferType & putEtx, unsigned int sizeLengthField,
40  unsigned int sizeMaxPayload, unsigned int sizeChecksumField, bool variableSizePayload)
41 {
42  size_stx = putStx.size();
43  size_etx = putEtx.size();
44  size_length_field = sizeLengthField;
45  variable_size_payload = variableSizePayload;
46  size_max_payload = sizeMaxPayload;
47  size_payload = variable_size_payload ? 0 : sizeMaxPayload;
48  size_checksum_field = sizeChecksumField;
49  STX = putStx;
50  ETX = putEtx;
53 
54  sig_warn.connect(sigslots_namespace + std::string("/ros_warn"));
55  sig_error.connect(sigslots_namespace + std::string("/ros_error"));
56 
57  //todo; exception
58  // Problem1: size_length_field = 1, vairable_size_payload = false
59 
60  clear();
61 }
62 
64 {
66  buffer.clear();
67 }
68 
70 {
71  verbose = true;
72 }
73 
75 {
76  return true;
77 }
78 
80 {
81  unsigned int num(0);
82 
83  switch (state)
84  {
85  case waitingForEtx:
86  num = 1;
87  break;
88 
91  break;
92 
94  num = size_checksum_field;
95  break;
96 
97  case waitingForStx:
98  case clearBuffer:
99  default:
100  num = 1;
101  break;
102  }
103 
104  if (verbose)
105  {
106  printf("[state(%d):%02d]", state, num);
107  }
108  return num;
109 }
110 
112 {
113  bufferRef = buffer;
114 }
115 
117 {
118  bufferRef.clear();
119 // std::cout<<"etx.size:"<<size_etx<<std::endl;
120  //bufferRef.resize( buffer.size() - size_stx - size_etx - size_length_field - size_checksum_field );
121 
122  bufferRef.resize( buffer.size() - size_stx - size_length_field - size_checksum_field );
123  //for (unsigned int i = size_stx + size_length_field; i < buffer.size() - size_etx - size_checksum_field; i++) {
124  for (unsigned int i = size_stx + size_length_field; i < buffer.size() - size_checksum_field; i++) {
125  bufferRef.push_back(buffer[i]);
126  }
127  std::cout<<"buffer.size:"<<buffer.size()<<std::endl;
128 
129 // ofstream outfile("~/debug.txt", ofstream::app);
130 // outfile<<"buffer size:"<<buffer.size()<<endl<<"stx size:"<<size_stx;
131 }
132 
140 bool PacketFinderBase::update(const unsigned char * incoming, unsigned int numberOfIncoming)
141 {
142  // clearBuffer = 0, waitingForStx, waitingForPayloadSize, waitingForPayloadToEtx, waitingForEtx,
143  // std::cout << "update [" << numberOfIncoming << "][" << state << "]" << std::endl;
144  if (!(numberOfIncoming > 0))
145  return false;
146 
147  bool found_packet(false);
148 
149  if ( state == clearBuffer ) {
150  buffer.clear();
152  }
153  switch (state)
154  {
155  case waitingForStx:
156  if (WaitForStx(incoming[0]))
157  {
158  if (size_length_field)
159  {
160  state = waitingForPayloadSize; // xbotbot
161  }
162  else
163  {
165  {
166  // e.g. stargazer
168  }
169  else
170  {
171  // e.g. iroboQ
172  //Todo; should put correct state
174  }
175  }
176  }
177  break;
178  case waitingForEtx:
179  if (waitForEtx(incoming[0], found_packet))
180  {
181  state = clearBuffer;
182  }
183  break;
184 
186  if (waitForPayloadSize(incoming, numberOfIncoming))
187  {
189  }
190  break;
191 
193  if (waitForPayloadAndEtx(incoming, numberOfIncoming, found_packet))
194  {
195  state = clearBuffer;
196  }
197  break;
198 
199  default:
201  break;
202  }
203  if ( found_packet ) {
204  return checkSum(); //what happen if checksum is equal to false(== -1)?
205  } else {
206  return false;
207  }
208 }
209 /*****************************************************************************
210 ** Protected
211 *****************************************************************************/
212 
213 bool PacketFinderBase::WaitForStx(const unsigned char datum)
214 {
215  bool found_stx(true);
216 
217  // add incoming datum
218  buffer.push_back(datum);
219 
220  // check whether we have STX
221  for (unsigned int i = 0; i < buffer.size() && i < STX.size(); i++)
222  {
223  if (buffer[i] != STX[i])
224  {
225  found_stx = false;
226  buffer.pop_front();
227  break;
228  }
229  }
230 
231  return (found_stx && buffer.size() == STX.size());
232 }
233 
234 bool PacketFinderBase::waitForPayloadSize(const unsigned char * incoming, unsigned int numberOfIncoming)
235 {
236  // push data
237  unsigned char first_byte;
238  for (unsigned int i = 0; i < numberOfIncoming; i++) {
239  first_byte = incoming[i];
240  buffer.push_back(incoming[i]);
241  }
242 
243  if (verbose)
244  {
245  for (unsigned int i = 0; i < buffer.size(); i++)
246  printf("%02x ", buffer[i]);
247  printf("\n");
248  }
249 
250  // check when we need to wait for etx
252  {
253  return false;
254  }
255  else
256  {
257  switch (size_length_field)
258  {
259  case 1: // xbot
261  break;
262  case 2:
264  size_payload |= buffer[size_stx + 1] << 8;
265  break;
266  case 4:
268  size_payload |= buffer[size_stx + 1] << 8;
269  size_payload |= buffer[size_stx + 2] << 16;
270  size_payload |= buffer[size_stx + 3] << 24;
271  break;
272  default:
273  // put assertion failure
274  size_payload = 1;
275  break;
276  }
277 
278  if (verbose)
279  {
280  printf("[payloadSize: %d]\n", size_payload);
281  }
282 
283  return true;
284  }
285 }
286 
287 bool PacketFinderBase::waitForEtx(const unsigned char incoming, bool & foundPacket)
288 {
289  // push data
290  buffer.push_back(incoming);
291 
292  // check when we need to wait for etx
293  // if minimum payload size is 1
294  if (buffer.size() < size_stx + size_etx + 1)
295  {
296  return false;
297  }
298  else
299  {
300  unsigned int number_of_match(0);
301  for (unsigned int i = 0; i < ETX.size(); i++)
302  {
303  if (buffer[buffer.size() - ETX.size() + i] == ETX[i])
304  {
305  number_of_match++;
306  }
307  }
308 
309  if (number_of_match == ETX.size())
310  {
311  foundPacket = true;
312  return true;
313  }
314 
316  return true;
317  else
318  return false;
319  }
320 }
321 
322 bool PacketFinderBase::waitForPayloadAndEtx(const unsigned char * incoming, unsigned int numberOfIncoming, bool & foundPacket)
323 {
324  // push data
325  for (unsigned int i = 0; i < numberOfIncoming; i++)
326  {
327  buffer.push_back(incoming[i]);
328  }
329  /*********************
330  ** Error Handling
331  **********************/
332  if ( size_payload > size_max_payload ) {
333  state = clearBuffer;
334  std::ostringstream ostream;
335  ostream << "abnormally sized payload retrieved, clearing [" << size_max_payload << "][" << size_payload << "]";
336 
337  ostream << std::setfill('0') << std::uppercase; //declare once, use everytime
338 // ostream.fill('0') //call once, affects everytime
339 // ostream.width(2); //need to call everytime
340 
341 /*
342  ostream << "[";
343  for (unsigned int i = 0; i < numberOfIncoming; ++i ) {
344  ostream.width(2); // need to declare evertime
345  ostream << std::hex << static_cast<int>(*(incoming+i)) << " " << std::dec;
346  }
347  ostream << "\b]";
348 */
349  ostream << ", buffer: [" << std::setw(2) << buffer.size() << "][";
350  for (unsigned int i = 0; i < buffer.size(); ++i ) {
351  ostream << std::setw(2) << std::hex << static_cast<int>(buffer[i]) << " " << std::dec;
352  }
353  ostream << "\b]";
354 
355  sig_error.emit(ostream.str());
356  return false;
357  }
358  // check when we need to wait for etx
360  {
361  return false;
362  }
363  else
364  {
365  if (verbose) {
366  std::cout << "Start check etx " << std::endl;
367  for (unsigned int i = 0; i < numberOfIncoming; ++i ) {
368  std::cout << std::hex << static_cast<int>(*(incoming+i)) << " ";
369  }
370  std::cout << std::dec << std::endl;
371  }
372  foundPacket = true;
373 
374  for (unsigned int i = (size_stx + size_length_field + size_payload + size_checksum_field);
376  {
377  if (buffer[i] != ETX[i])
378  {
379  foundPacket = false;
380  }
381  }
382  if (verbose)
383  std::cout << "End of checking etx " << std::endl;
384  return true;
385  }
386 }
387 
388 
389 } // namespace xbot
bool WaitForStx(const unsigned char datum)
enum packetFinderState state
unsigned int size() const
bool waitForPayloadAndEtx(const unsigned char *incoming, unsigned int numberOfIncoming, bool &foundPacket)
ecl::Signal< const std::string & > sig_error
unsigned int size_checksum_field
EndOfLine endl
void push_back(const Type &datum)
void configure(const std::string &sigslots_namespace, const BufferType &putStx, const BufferType &putEtx, unsigned int sizeLengthField, unsigned int sizeMaxPayload, unsigned int sizeChecksumField, bool variableSizePayload)
bool waitForEtx(const unsigned char incoming, bool &foundPacket)
ecl::PushAndPop< unsigned char > BufferType
ecl::Signal< const std::string & > sig_warn
virtual bool checkSum()
virtual bool update(const unsigned char *incoming, unsigned int numberOfIncoming)
unsigned int size_length_field
void getBuffer(BufferType &bufferRef)
unsigned int size_max_payload
void connect(const std::string &topic)
Definition: command.hpp:30
void emit(Data data)
void getPayload(BufferType &bufferRef)
unsigned int numberOfDataToRead()
bool waitForPayloadSize(const unsigned char *incoming, unsigned int numberOfIncoming)


xbot_driver
Author(s): Roc, wangpeng@droid.ac.cn
autogenerated on Sat Oct 10 2020 03:27:37