Goby v2
test.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 // tests functionality of the UDPDriver with respect to multiple frames & acknowledgments
23 
24 #include "goby/acomms/modemdriver/udp_driver.h"
25 
26 #include "goby/acomms/acomms_helpers.h"
27 #include "goby/acomms/bind.h"
28 #include "goby/acomms/connect.h"
29 #include "goby/acomms/queue.h"
30 #include "goby/common/logger.h"
31 #include "goby/util/binary.h"
32 #include "test.pb.h"
33 #include <cstdlib>
34 
35 boost::asio::io_service io1, io2;
36 boost::shared_ptr<goby::acomms::ModemDriverBase> driver1, driver2;
38 GobyMessage msg_in1, msg_in2;
39 bool received_ack = false;
40 
41 using namespace goby::acomms;
42 
43 void handle_ack(const goby::acomms::protobuf::ModemTransmission& ack_msg,
44  const google::protobuf::Message& orig_msg);
45 
46 void qsize(goby::acomms::protobuf::QueueSize size);
47 
48 void handle_receive(const google::protobuf::Message& msg);
49 void handle_data_receive1(const protobuf::ModemTransmission& msg);
50 
51 void test5()
52 {
53  msg_in1.set_telegram("hello!");
54  msg_in1.mutable_header()->set_time(
55  goby::util::as<goby::uint64>(boost::posix_time::second_clock::universal_time()));
56  msg_in1.mutable_header()->set_source_platform(1);
57  msg_in1.mutable_header()->set_dest_platform(2);
58  msg_in1.mutable_header()->set_dest_type(Header::PUBLISH_OTHER);
59  msg_in1.set_telegram("hello 1");
60 
61  msg_in2 = msg_in1;
62  msg_in2.set_telegram("hello 2");
63 
64  std::cout << "Pushed: " << msg_in2 << std::endl;
65  q1.push_message(msg_in2);
66  std::cout << "Pushed: " << msg_in1 << std::endl;
67  q1.push_message(msg_in1);
68 
70 
71  transmit.set_type(protobuf::ModemTransmission::DATA);
72  transmit.set_src(1);
73  transmit.set_dest(2);
74  transmit.set_rate(2);
75  transmit.set_ack_requested(true);
76  transmit.set_max_frame_bytes(15);
77 
78  // spoof a data request
79  transmit.set_frame_start(0);
80  q1.handle_modem_data_request(&transmit);
81  assert(transmit.frame_size() == 1);
82  // clear the data "lose it in transmission"
83  transmit.clear_frame();
84 
85  transmit.set_frame_start(1);
86  driver1->handle_initiate_transmission(transmit);
87 
88  int i = 0;
89  while (((i / 10) < 60) && !received_ack)
90  {
91  driver1->do_work();
92  driver2->do_work();
93 
94  usleep(100000);
95  ++i;
96  }
97 
98  usleep(100000);
99  transmit.clear_frame();
100  transmit.set_frame_start(2);
101  q1.handle_modem_data_request(&transmit);
102  assert(transmit.frame_size() == 1);
103 }
104 
105 int main(int argc, char* argv[])
106 {
107  goby::glog.add_stream(goby::common::logger::DEBUG3, &std::clog);
108  std::ofstream fout;
109 
110  if (argc == 2)
111  {
112  fout.open(argv[1]);
113  goby::glog.add_stream(goby::common::logger::DEBUG3, &fout);
114  }
115 
116  goby::glog.set_name(argv[0]);
117 
118  driver1.reset(new goby::acomms::UDPDriver(&io1));
119  driver2.reset(new goby::acomms::UDPDriver(&io2));
120 
122 
123  cfg1.set_modem_id(1);
124 
125  srand(time(NULL));
126  int port1 = rand() % 1000 + 50010;
127  int port2 = port1 + 1;
128 
129  //gumstix
130  UDPDriverConfig::EndPoint* local_endpoint1 = cfg1.MutableExtension(UDPDriverConfig::local);
131  local_endpoint1->set_port(port1);
132 
133  cfg2.set_modem_id(2);
134 
135  // shore
136  UDPDriverConfig::EndPoint* local_endpoint2 = cfg2.MutableExtension(UDPDriverConfig::local);
137  local_endpoint2->set_port(port2);
138 
139  UDPDriverConfig::EndPoint* remote_endpoint1 = cfg1.MutableExtension(UDPDriverConfig::remote);
140 
141  remote_endpoint1->set_ip("localhost");
142  remote_endpoint1->set_port(port2);
143 
144  UDPDriverConfig::EndPoint* remote_endpoint2 = cfg2.MutableExtension(UDPDriverConfig::remote);
145 
146  remote_endpoint2->set_ip("127.0.0.1");
147  remote_endpoint2->set_port(port1);
148 
149  cfg1.SetExtension(UDPDriverConfig::max_frame_size, 15);
150  cfg2.SetExtension(UDPDriverConfig::max_frame_size, 15);
151 
153  qcfg1.set_modem_id(1);
154  qcfg1.set_minimum_ack_wait_seconds(.1);
155 
156  goby::acomms::protobuf::QueuedMessageEntry* q_entry = qcfg1.add_message_entry();
157  q_entry->set_protobuf_name("GobyMessage");
158  q_entry->set_newest_first(true);
159 
160  goby::acomms::protobuf::QueuedMessageEntry::Role* src_role = q_entry->add_role();
161  src_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::SOURCE_ID);
162  src_role->set_field("header.source_platform");
163 
164  goby::acomms::protobuf::QueuedMessageEntry::Role* dest_role = q_entry->add_role();
165  dest_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::DESTINATION_ID);
166  dest_role->set_field("header.dest_platform");
167 
168  goby::acomms::protobuf::QueuedMessageEntry::Role* time_role = q_entry->add_role();
169  time_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::TIMESTAMP);
170  time_role->set_field("header.time");
171 
172  qcfg2 = qcfg1;
173  qcfg2.set_modem_id(2);
174 
175  q1.set_cfg(qcfg1);
176  q2.set_cfg(qcfg2);
177 
178  goby::glog.add_group("test", goby::common::Colors::green);
179  goby::glog.add_group("driver1", goby::common::Colors::green);
180  goby::glog.add_group("driver2", goby::common::Colors::yellow);
181 
182  goby::acomms::connect(&q2.signal_receive, &handle_receive);
184  goby::acomms::connect(&q1.signal_ack, &handle_ack);
185  goby::acomms::bind(*driver1, q1);
186  goby::acomms::bind(*driver2, q2);
187 
188  goby::acomms::connect(&driver1->signal_receive, handle_data_receive1);
189 
190  goby::glog << cfg1.DebugString() << std::endl;
191  goby::glog << cfg2.DebugString() << std::endl;
192 
193  goby::glog << qcfg1.DebugString() << std::endl;
194  goby::glog << qcfg2.DebugString() << std::endl;
195 
196  driver1->startup(cfg1);
197  driver2->startup(cfg2);
198 
199  test5();
200 
201  std::cout << "all tests passed." << std::endl;
202  return 0;
203 }
204 
205 void handle_receive(const google::protobuf::Message& msg)
206 {
207  std::cout << "Received: " << msg << std::endl;
208 }
209 
210 void qsize(goby::acomms::protobuf::QueueSize size)
211 {
212  std::cout << "Queue size: " << size.size() << std::endl;
213 }
214 
215 void handle_ack(const goby::acomms::protobuf::ModemTransmission& ack_msg,
216  const google::protobuf::Message& orig_msg)
217 {
218  std::cout << "got an ack: " << ack_msg << "\n"
219  << "of original: " << orig_msg << std::endl;
220  assert(orig_msg.SerializeAsString() == msg_in2.SerializeAsString());
221 }
222 
223 void handle_data_receive1(const protobuf::ModemTransmission& msg)
224 {
225  if (msg.type() == protobuf::ModemTransmission::ACK)
226  received_ack = true;
227 }
provides an API to the goby-acomms Queuing Library.
Definition: queue_manager.h:49
boost::signals2::signal< void(const protobuf::ModemTransmission &ack_msg, const google::protobuf::Message &orig_msg)> signal_ack
Signals when acknowledgment of proper message receipt has been received. This is only sent for queues...
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
Definition: flex_ostream.h:67
boost::signals2::signal< void(const google::protobuf::Message &msg)> signal_receive
Signals when a DCCL message is received.
void handle_modem_data_request(protobuf::ModemTransmission *msg)
Finds data to send to the modem.
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)
void set_cfg(const protobuf::QueueManagerConfig &cfg)
Set (and overwrite completely if present) the current configuration. (protobuf::QueueManagerConfig de...
boost::signals2::signal< void(protobuf::QueueSize size)> signal_queue_size_change
Signals when any queue changes size (message is popped or pushed)
void add_stream(logger::Verbosity verbosity=logger::VERBOSE, std::ostream *os=0)
Attach a stream object (e.g. std::cout, std::ofstream, ...) to the logger with desired verbosity...
Definition: flex_ostream.h:96
void bind(ModemDriverBase &driver, QueueManager &queue_manager)
binds the driver link-layer callbacks to the QueueManager
Definition: bind.h:43
void push_message(const google::protobuf::Message &new_message)
Push a message (and add the queue if it does not exist)