Goby v2
driver_tester.cpp
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 //
5 //
6 // This file is part of the Goby Underwater Autonomy Project Binaries
7 // ("The Goby Binaries").
8 //
9 // The Goby Binaries are free software: you can redistribute them and/or modify
10 // them under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // The Goby Binaries are distributed in the hope that they will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
21 
22 #include "driver_tester.h"
23 
24 using namespace goby::common::logger;
25 using namespace goby::acomms;
27 using goby::util::as;
28 using namespace boost::posix_time;
29 
30 DriverTester::DriverTester(boost::shared_ptr<goby::acomms::ModemDriverBase> driver1,
31  boost::shared_ptr<goby::acomms::ModemDriverBase> driver2,
34  const std::vector<int>& tests_to_run,
35  goby::acomms::protobuf::DriverType driver_type)
36 
37  : driver1_(driver1), driver2_(driver2), check_count_(0), tests_to_run_(tests_to_run),
38  tests_to_run_index_(0), test_number_(-1), driver_type_(driver_type)
39 {
40  goby::glog.add_group("test", goby::common::Colors::green);
41  goby::glog.add_group("driver1", goby::common::Colors::green);
42  goby::glog.add_group("driver2", goby::common::Colors::yellow);
43 
44  goby::acomms::connect(&driver1_->signal_receive, this, &DriverTester::handle_data_receive1);
45  goby::acomms::connect(&driver1_->signal_transmit_result, this,
46  &DriverTester::handle_transmit_result1);
47  goby::acomms::connect(&driver1_->signal_modify_transmission, this,
48  &DriverTester::handle_modify_transmission1);
49  goby::acomms::connect(&driver1_->signal_data_request, this,
50  &DriverTester::handle_data_request1);
51  goby::acomms::connect(&driver2_->signal_receive, this, &DriverTester::handle_data_receive2);
52  goby::acomms::connect(&driver2_->signal_transmit_result, this,
53  &DriverTester::handle_transmit_result2);
54  goby::acomms::connect(&driver2_->signal_modify_transmission, this,
55  &DriverTester::handle_modify_transmission2);
56  goby::acomms::connect(&driver2_->signal_data_request, this,
57  &DriverTester::handle_data_request2);
58 
59  goby::glog << cfg1.DebugString() << std::endl;
60  goby::glog << cfg2.DebugString() << std::endl;
61 
62  driver1_->startup(cfg1);
63  driver2_->startup(cfg2);
64 
65  int i = 0;
66  while (((i / 10) < 3))
67  {
68  driver1_->do_work();
69  driver2_->do_work();
70 
71  usleep(100000);
72  ++i;
73  }
74 
75  test_str0_.resize(32);
76  for (std::string::size_type i = 0, n = test_str0_.size(); i < n; ++i) test_str0_[i] = i;
77 
78  test_str1_.resize(64);
79  for (std::string::size_type i = 0, n = test_str1_.size(); i < n; ++i)
80  test_str1_[i] = i + 64; // skip by some of low bits
81 
82  test_str2_.resize(64);
83  for (std::string::size_type i = 0, n = test_str2_.size(); i < n; ++i)
84  test_str2_[i] = i + 2 * 64;
85 
86  test_str3_.resize(64);
87  for (std::string::size_type i = 0, n = test_str3_.size(); i < n; ++i)
88  test_str3_[i] = i + 3 * 64;
89 
90  test_number_ = tests_to_run_[tests_to_run_index_];
91 }
92 
93 int DriverTester::run()
94 {
95  try
96  {
97  for (;;)
98  {
99  switch (test_number_)
100  {
101  case 0: test0(); break;
102  case 1: test1(); break;
103  case 2: test2(); break;
104  case 3: test3(); break;
105  case 4: test4(); break;
106  case 5: test5(); break;
107  case 6: test6(); break;
108  case -1:
109  goby::glog << group("test") << "all tests passed" << std::endl;
110  driver1_->shutdown();
111  driver2_->shutdown();
112 
113  return 0;
114  }
115 
116  goby::glog << "Test " << group("test") << test_number_ << " passed." << std::endl;
117  ++tests_to_run_index_;
118 
119  if (tests_to_run_index_ < static_cast<int>(tests_to_run_.size()))
120  test_number_ = tests_to_run_[tests_to_run_index_];
121  else
122  test_number_ = -1;
123 
124  check_count_ = 0;
125  sleep(1);
126  }
127  }
128  catch (std::exception& e)
129  {
130  goby::glog << warn << "Exception: " << e.what() << std::endl;
131  sleep(5);
132  exit(2);
133  }
134 }
135 
136 void DriverTester::handle_data_request1(protobuf::ModemTransmission* msg)
137 {
138  goby::glog << group("driver1") << "Data request: " << *msg << std::endl;
139 
140  switch (test_number_)
141  {
142  case 4:
143  {
144  msg->add_frame(test_str0_);
145  static bool entered = false;
146  if (!entered)
147  {
148  ++check_count_;
149  entered = true;
150  }
151  }
152  break;
153 
154  case 5:
155  {
156  static bool entered = false;
157  msg->add_frame(test_str2_);
158  msg->add_frame(test_str3_);
159  if (!entered)
160  {
161  ++check_count_;
162  entered = true;
163  }
164  }
165  break;
166  }
167 
168  goby::glog << group("driver1") << "Post data request: " << *msg << std::endl;
169 }
170 
171 void DriverTester::handle_modify_transmission1(protobuf::ModemTransmission* msg)
172 {
173  goby::glog << group("driver1") << "Can modify: " << *msg << std::endl;
174 }
175 
176 void DriverTester::handle_transmit_result1(const protobuf::ModemTransmission& msg)
177 {
178  goby::glog << group("driver1") << "Completed transmit: " << msg << std::endl;
179 }
180 
181 void DriverTester::handle_data_receive1(const protobuf::ModemTransmission& msg)
182 {
183  goby::glog << group("driver1") << "Received: " << msg << std::endl;
184 
185  switch (test_number_)
186  {
187  case 0:
188  {
189  if (driver_type_ == goby::acomms::protobuf::DRIVER_WHOI_MICROMODEM)
190  {
191  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
192  msg.GetExtension(micromodem::protobuf::type) ==
193  micromodem::protobuf::MICROMODEM_TWO_WAY_PING);
194  ++check_count_;
195  }
196  else if (driver_type_ == goby::acomms::protobuf::DRIVER_BENTHOS_ATM900)
197  {
198  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
199  msg.GetExtension(benthos::protobuf::type) ==
200  benthos::protobuf::BENTHOS_TWO_WAY_PING);
201  ++check_count_;
202  }
203  break;
204  }
205 
206  case 1:
207  {
208  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
209  msg.GetExtension(micromodem::protobuf::type) ==
210  micromodem::protobuf::MICROMODEM_REMUS_LBL_RANGING);
211 
212  assert(msg.src() == 1);
213  assert(!msg.has_dest());
214 
215  ptime now = goby_time();
216  ptime reported = as<ptime>(msg.time());
217  assert(reported < now && reported > now - seconds(2));
218  ++check_count_;
219  }
220  break;
221 
222  case 2:
223  {
224  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
225  msg.GetExtension(micromodem::protobuf::type) ==
226  micromodem::protobuf::MICROMODEM_NARROWBAND_LBL_RANGING);
227 
228  assert(msg.src() == 1);
229  assert(!msg.has_dest());
230 
231  ptime now = goby_time();
232  ptime reported = as<ptime>(msg.time());
233  assert(reported < now && reported > now - seconds(2));
234  ++check_count_;
235  }
236  break;
237 
238  case 3:
239  {
240  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
241  msg.GetExtension(micromodem::protobuf::type) ==
242  micromodem::protobuf::MICROMODEM_MINI_DATA);
243 
244  assert(msg.src() == 2);
245  assert(msg.dest() == 1);
246  assert(msg.frame_size() == 1);
247  assert(msg.frame(0) == goby::util::hex_decode("0123"));
248  ++check_count_;
249  }
250  break;
251 
252  case 4:
253  {
254  assert(msg.type() == protobuf::ModemTransmission::ACK);
255  assert(msg.src() == 2);
256  assert(msg.dest() == 1);
257  assert(msg.acked_frame_size() == 1 && msg.acked_frame(0) == 0);
258  ++check_count_;
259  }
260  break;
261 
262  case 5:
263  {
264  assert(msg.type() == protobuf::ModemTransmission::ACK);
265  assert(msg.src() == 2);
266  assert(msg.dest() == 1);
267  assert(msg.acked_frame_size() == 3 && msg.acked_frame(1) == msg.acked_frame(0) + 1 &&
268  msg.acked_frame(2) == msg.acked_frame(0) + 2);
269  ++check_count_;
270  }
271  break;
272 
273  case 6:
274  {
275  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
276  msg.GetExtension(micromodem::protobuf::type) ==
277  micromodem::protobuf::MICROMODEM_FLEXIBLE_DATA);
278 
279  assert(msg.src() == 2);
280  assert(msg.dest() == 1);
281  assert(msg.rate() == 1);
282  assert(msg.frame_size() == 1);
283 
284  std::cout << "[" << goby::util::hex_encode(msg.frame(0)) << "]" << std::endl;
285  assert(msg.frame(0) ==
286  goby::util::hex_decode("00112233445566778899001122334455667788990011"));
287  ++check_count_;
288  }
289  break;
290 
291  default: break;
292  }
293 }
294 
295 void DriverTester::handle_data_request2(protobuf::ModemTransmission* msg)
296 {
297  goby::glog << group("driver2") << "Data request: " << *msg << std::endl;
298 
299  switch (test_number_)
300  {
301  default: assert(false); break;
302 
303  case 3:
304  {
305  static bool entered = false;
306  if (!entered)
307  {
308  ++check_count_;
309  entered = true;
310  }
311 
312  msg->add_frame(goby::util::hex_decode("0123"));
313  break;
314  }
315 
316  case 4: break;
317 
318  case 6:
319  {
320  static bool entered = false;
321  if (!entered)
322  {
323  ++check_count_;
324  entered = true;
325  }
326 
327  msg->add_frame(goby::util::hex_decode("00112233445566778899001122334455667788990011"));
328  break;
329  }
330  }
331 
332  goby::glog << group("driver2") << "Post data request: " << *msg << std::endl;
333 }
334 
335 void DriverTester::handle_modify_transmission2(protobuf::ModemTransmission* msg)
336 {
337  goby::glog << group("driver2") << "Can modify: " << *msg << std::endl;
338 }
339 
340 void DriverTester::handle_transmit_result2(const protobuf::ModemTransmission& msg)
341 {
342  goby::glog << group("driver2") << "Completed transmit: " << msg << std::endl;
343 }
344 
345 void DriverTester::handle_data_receive2(const protobuf::ModemTransmission& msg)
346 {
347  goby::glog << group("driver2") << "Received: " << msg << std::endl;
348 
349  switch (test_number_)
350  {
351  default: break;
352 
353  case 0:
354  if (driver_type_ == goby::acomms::protobuf::DRIVER_WHOI_MICROMODEM)
355  {
356  assert(msg.type() == protobuf::ModemTransmission::DRIVER_SPECIFIC &&
357  msg.GetExtension(micromodem::protobuf::type) ==
358  micromodem::protobuf::MICROMODEM_TWO_WAY_PING);
359  ++check_count_;
360  }
361  break;
362 
363  case 4:
364  {
365  if (msg.type() == protobuf::ModemTransmission::DATA)
366  {
367  assert(msg.src() == 1);
368  assert(msg.dest() == 2);
369  assert(msg.frame_size() == 1);
370  assert(msg.frame(0) == test_str0_);
371  ++check_count_;
372  }
373 
374  break;
375  }
376 
377  case 5:
378  if (msg.type() == protobuf::ModemTransmission::DATA)
379  {
380  assert(msg.src() == 1);
381  assert(msg.dest() == 2);
382  assert(msg.frame_size() == 3);
383  assert(msg.frame(0) == test_str1_);
384  assert(msg.frame(1) == test_str2_);
385  assert(msg.frame(2) == test_str3_);
386  ++check_count_;
387  }
388  break;
389  }
390 }
391 
392 void DriverTester::test0()
393 {
394  // ping test
395  goby::glog << group("test") << "Ping test" << std::endl;
396 
398 
399  transmit.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC);
400 
401  if (driver_type_ == goby::acomms::protobuf::DRIVER_WHOI_MICROMODEM)
402  transmit.SetExtension(micromodem::protobuf::type,
403  micromodem::protobuf::MICROMODEM_TWO_WAY_PING);
404  else if (driver_type_ == goby::acomms::protobuf::DRIVER_BENTHOS_ATM900)
405  transmit.SetExtension(benthos::protobuf::type, benthos::protobuf::BENTHOS_TWO_WAY_PING);
406 
407  transmit.set_src(1);
408  transmit.set_dest(2);
409 
410  driver1_->handle_initiate_transmission(transmit);
411 
412  int i = 0;
413  while (((i / 10) < 10) && check_count_ < 2)
414  {
415  driver1_->do_work();
416  driver2_->do_work();
417 
418  usleep(100000);
419  ++i;
420  }
421 
422  if (driver_type_ == goby::acomms::protobuf::DRIVER_WHOI_MICROMODEM)
423  assert(check_count_ == 2);
424  else if (driver_type_ == goby::acomms::protobuf::DRIVER_BENTHOS_ATM900)
425  assert(check_count_ == 1); // no clear indication of ping on the pinged modem
426 }
427 
428 void DriverTester::test1()
429 {
430  goby::glog << group("test") << "Remus LBL test" << std::endl;
431 
433 
434  transmit.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC);
435  transmit.SetExtension(micromodem::protobuf::type,
436  micromodem::protobuf::MICROMODEM_REMUS_LBL_RANGING);
437 
438  transmit.set_src(1);
439  transmit.MutableExtension(micromodem::protobuf::remus_lbl)->set_lbl_max_range(1000);
440 
441  driver1_->handle_initiate_transmission(transmit);
442 
443  int i = 0;
444  while (((i / 10) < 10) && check_count_ < 1)
445  {
446  driver1_->do_work();
447  driver2_->do_work();
448 
449  usleep(100000);
450  ++i;
451  }
452  assert(check_count_ == 1);
453 }
454 
455 void DriverTester::test2()
456 {
457  goby::glog << group("test") << "Narrowband LBL test" << std::endl;
458 
460 
461  transmit.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC);
462  transmit.SetExtension(micromodem::protobuf::type,
463  micromodem::protobuf::MICROMODEM_NARROWBAND_LBL_RANGING);
464  transmit.set_src(1);
465 
467  transmit.MutableExtension(micromodem::protobuf::narrowband_lbl);
468  params->set_lbl_max_range(1000);
469  params->set_turnaround_ms(20);
470  params->set_transmit_freq(26000);
471  params->set_transmit_ping_ms(5);
472  params->set_receive_ping_ms(5);
473  params->add_receive_freq(25000);
474  params->set_transmit_flag(true);
475 
476  driver1_->handle_initiate_transmission(transmit);
477 
478  int i = 0;
479  while (((i / 10) < 10) && check_count_ < 1)
480  {
481  driver1_->do_work();
482  driver2_->do_work();
483 
484  usleep(100000);
485  ++i;
486  }
487  assert(check_count_ == 1);
488 }
489 
490 void DriverTester::test3()
491 {
492  goby::glog << group("test") << "Mini data test" << std::endl;
493 
495 
496  transmit.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC);
497  transmit.SetExtension(micromodem::protobuf::type, micromodem::protobuf::MICROMODEM_MINI_DATA);
498 
499  transmit.set_src(2);
500  transmit.set_dest(1);
501 
502  driver2_->handle_initiate_transmission(transmit);
503 
504  int i = 0;
505  while (((i / 10) < 10) && check_count_ < 2)
506  {
507  driver1_->do_work();
508  driver2_->do_work();
509 
510  usleep(100000);
511  ++i;
512  }
513  assert(check_count_ == 2);
514 }
515 
516 void DriverTester::test4()
517 {
518  goby::glog << group("test") << "Rate 0 test" << std::endl;
519 
521 
522  transmit.set_type(protobuf::ModemTransmission::DATA);
523  transmit.set_src(1);
524  transmit.set_dest(2);
525  transmit.set_rate(0);
526  transmit.set_ack_requested(true);
527  // transmit.set_ack_requested(false);
528  driver1_->handle_initiate_transmission(transmit);
529 
530  int i = 0;
531  while (((i / 10) < 60) && check_count_ < 3)
532  {
533  driver1_->do_work();
534  driver2_->do_work();
535 
536  usleep(100000);
537  ++i;
538  }
539  assert(check_count_ == 3);
540 }
541 
542 void DriverTester::test5()
543 {
544  goby::glog << group("test") << "Rate 2 test" << std::endl;
545 
547 
548  transmit.set_type(protobuf::ModemTransmission::DATA);
549  transmit.set_src(1);
550  transmit.set_dest(2);
551  transmit.set_rate(2);
552 
553  transmit.add_frame(test_str1_);
554  transmit.set_ack_requested(true);
555 
556  driver1_->handle_initiate_transmission(transmit);
557 
558  int i = 0;
559  while (((i / 10) < 60) && check_count_ < 3)
560  {
561  driver1_->do_work();
562  driver2_->do_work();
563 
564  usleep(100000);
565  ++i;
566  }
567  assert(check_count_ == 3);
568 }
569 
570 void DriverTester::test6()
571 {
572  goby::glog << group("test") << "FDP data test" << std::endl;
573 
575 
576  transmit.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC);
577  transmit.SetExtension(micromodem::protobuf::type,
578  micromodem::protobuf::MICROMODEM_FLEXIBLE_DATA);
579 
580  dynamic_cast<goby::acomms::MMDriver*>(driver1_.get())
581  ->write_single_cfg("psk.packet.mod_hdr_version,1");
582  dynamic_cast<goby::acomms::MMDriver*>(driver2_.get())
583  ->write_single_cfg("psk.packet.mod_hdr_version,1");
584 
585  transmit.set_src(2);
586  transmit.set_dest(1);
587  transmit.set_rate(1);
588 
589  driver2_->handle_initiate_transmission(transmit);
590 
591  int i = 0;
592  while (((i / 10) < 10) && check_count_ < 2)
593  {
594  driver1_->do_work();
595  driver2_->do_work();
596 
597  usleep(100000);
598  ++i;
599  }
600  assert(check_count_ == 2);
601 }
provides an API to the WHOI Micro-Modem driver
Definition: mm_driver.h:41
ReturnType goby_time()
Returns current UTC time as a boost::posix_time::ptime.
Definition: time.h:104
void add_group(const std::string &name, Colors::Color color=Colors::nocolor, const std::string &description="")
Add another group to the logger. A group provides related manipulator for categorizing log messages...
void connect(Signal *signal, Slot slot)
connect a signal to a slot (e.g. function pointer)
Definition: connect.h:36
common::FlexOstream glog
Access the Goby logger through this object.
Objects pertaining to acoustic communications (acomms)