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 0.1 --> route_manager --> 1.1 --> 2.1 route
23 
24 // id 1.1 2.1 3.1
25 //
26 // ------->Router------- out
27 // | | ^
28 // | v |
29 // QueueManager QueueManager QueueManager
30 // ^ | ^
31 // | v |
32 // in Driver ------> Driver
33 
34 #include "goby/acomms/acomms_helpers.h"
35 #include "goby/acomms/amac/mac_manager.h"
36 #include "goby/acomms/bind.h"
37 #include "goby/acomms/connect.h"
38 #include "goby/acomms/modemdriver/udp_driver.h"
39 #include "goby/acomms/route/route.h"
40 #include "goby/common/logger.h"
41 #include "goby/common/time.h"
42 #include "goby/util/as.h"
43 #include "goby/util/binary.h"
44 #include "test.pb.h"
45 #include <cstdlib>
46 
47 using namespace goby::common::logger;
48 using namespace goby::acomms;
50 using goby::util::as;
51 using namespace boost::posix_time;
52 
53 const int ID_0_1 = 1;
54 const int ID_1_1 = (1 << 8) + 1;
55 const int ID_2_1 = (2 << 8) + 1;
56 const int ID_3_1 = (3 << 8) + 1;
57 
58 void handle_receive1(const google::protobuf::Message& msg);
59 void handle_receive2(const google::protobuf::Message& msg);
60 void handle_receive3(const google::protobuf::Message& msg);
61 
62 void handle_modem_receive3(const protobuf::ModemTransmission& message);
63 
64 boost::asio::io_service io2, io3;
65 boost::shared_ptr<goby::acomms::UDPDriver> driver2, driver3;
66 
67 bool received_message = false;
68 
69 RouteMessage in_msg;
70 
71 int main(int argc, char* argv[])
72 {
73  goby::glog.add_stream(goby::common::logger::DEBUG3, &std::clog);
74  goby::glog.set_name(argv[0]);
75 
76  // set up queues
77  goby::acomms::QueueManager q_manager1, q_manager2, q_manager3;
78  goby::acomms::protobuf::QueueManagerConfig q_cfg1, q_cfg2, q_cfg3;
79  goby::acomms::protobuf::QueuedMessageEntry* q_entry = q_cfg1.add_message_entry();
80  q_entry->set_protobuf_name("RouteMessage");
81  q_entry->set_newest_first(true);
82 
83  goby::acomms::protobuf::QueuedMessageEntry::Role* src_role = q_entry->add_role();
84  src_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::SOURCE_ID);
85  src_role->set_field("src");
86 
87  goby::acomms::protobuf::QueuedMessageEntry::Role* dest_role = q_entry->add_role();
88  dest_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::DESTINATION_ID);
89  dest_role->set_field("dest");
90 
91  goby::acomms::protobuf::QueuedMessageEntry::Role* time_role = q_entry->add_role();
92  time_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::TIMESTAMP);
93  time_role->set_field("time");
94 
95  q_cfg2.add_message_entry()->CopyFrom(*q_entry);
96  q_cfg3.add_message_entry()->CopyFrom(*q_entry);
97 
98  q_cfg1.set_skip_decoding(true);
99  q_cfg2.set_skip_decoding(true);
100  q_cfg3.set_skip_decoding(false);
101 
102  q_cfg1.set_modem_id(ID_1_1);
103  q_manager1.set_cfg(q_cfg1);
104 
105  q_cfg2.set_modem_id(ID_2_1);
106  q_manager2.set_cfg(q_cfg2);
107 
108  q_cfg3.set_modem_id(ID_3_1);
109  q_manager3.set_cfg(q_cfg3);
110 
111  // connect our receive callback
112  goby::acomms::connect(&q_manager1.signal_receive, &handle_receive1);
113  goby::acomms::connect(&q_manager2.signal_receive, &handle_receive2);
114  goby::acomms::connect(&q_manager3.signal_receive, &handle_receive3);
115 
116  // set up the router
117  goby::acomms::RouteManager r_manager;
119  r_cfg.mutable_route()->add_hop(ID_0_1);
120  r_cfg.mutable_route()->add_hop(ID_1_1);
121  r_cfg.mutable_route()->add_hop(ID_2_1);
122  r_cfg.mutable_route()->add_hop(ID_3_1);
123  r_cfg.set_subnet_mask(0xFFFFFF00);
124  r_manager.set_cfg(r_cfg);
125 
126  // set up drivers
127  driver2.reset(new goby::acomms::UDPDriver(&io2));
128  driver3.reset(new goby::acomms::UDPDriver(&io3));
129 
131  d_cfg2.set_modem_id(ID_2_1);
132  d_cfg3.set_modem_id(ID_3_1);
133 
134  srand(time(NULL));
135  int port1 = rand() % 1000 + 50020;
136  int port2 = port1 + 1;
137 
138  d_cfg2.MutableExtension(UDPDriverConfig::local)->set_port(port1);
139  d_cfg3.MutableExtension(UDPDriverConfig::local)->set_port(port2);
140  d_cfg2.MutableExtension(UDPDriverConfig::remote)
141  ->CopyFrom(d_cfg3.GetExtension(UDPDriverConfig::local));
142  d_cfg3.MutableExtension(UDPDriverConfig::remote)
143  ->CopyFrom(d_cfg2.GetExtension(UDPDriverConfig::local));
144 
145  driver2->startup(d_cfg2);
146  driver3->startup(d_cfg3);
147 
148  // set up two MACManagers to handle the drivers
149  goby::acomms::MACManager mac2, mac3;
150  goby::acomms::protobuf::MACConfig m_cfg2, m_cfg3;
151  m_cfg2.set_modem_id(ID_2_1);
152  m_cfg3.set_modem_id(ID_3_1);
153  m_cfg2.set_type(goby::acomms::protobuf::MAC_FIXED_DECENTRALIZED);
154  m_cfg3.set_type(goby::acomms::protobuf::MAC_FIXED_DECENTRALIZED);
155 
157  slot2.set_src(ID_2_1);
158  slot2.set_type(goby::acomms::protobuf::ModemTransmission::DATA);
159  slot2.set_slot_seconds(0.1);
160  m_cfg2.add_slot()->CopyFrom(slot2);
161  m_cfg3.add_slot()->CopyFrom(slot2);
162 
164  slot3.set_src(ID_3_1);
165  slot3.set_type(goby::acomms::protobuf::ModemTransmission::DATA);
166  slot3.set_slot_seconds(0.1);
167  m_cfg2.add_slot()->CopyFrom(slot3);
168  m_cfg3.add_slot()->CopyFrom(slot3);
169 
170  mac2.startup(m_cfg2);
171  mac3.startup(m_cfg3);
172 
173  // renable crypto when we receive on driver3
174  goby::acomms::connect(&driver3->signal_receive, &handle_modem_receive3);
175 
176  // bind them all together
177  goby::acomms::bind(*driver2, q_manager2, mac2);
178  goby::acomms::bind(*driver3, q_manager3, mac3);
179 
180  goby::acomms::bind(q_manager1, r_manager);
181  goby::acomms::bind(q_manager2, r_manager);
182 
183  // create a message
184  in_msg.set_src(ID_0_1);
185  in_msg.set_dest(ID_3_1);
186  in_msg.set_time(goby_time<goby::uint64>() / 1000000 *
187  1000000); // integer second for _time codec
188  in_msg.set_telegram("0-->3");
189 
190  // create transmission from message
192  initial_transmit.set_src(ID_0_1);
193  initial_transmit.set_dest(ID_1_1);
194  initial_transmit.set_time(goby_time<goby::uint64>());
195  initial_transmit.set_type(goby::acomms::protobuf::ModemTransmission::DATA);
196 
198 
200  dccl_cfg.set_crypto_passphrase("my_passphrase2!");
201  dccl->set_cfg(dccl_cfg);
202 
203  dccl->validate<RouteMessage>();
204  dccl->encode(initial_transmit.add_frame(), in_msg);
205 
206  // remove crypto
207  dccl_cfg.clear_crypto_passphrase();
208  dccl->set_cfg(dccl_cfg);
209 
210  // unleash the message
211  std::cout << "Modem receive on q1: " << initial_transmit.DebugString() << std::endl;
212  q_manager1.handle_modem_receive(initial_transmit);
213 
214  int i = 0;
215 
216  while (((i / 10) < 10))
217  {
218  driver2->do_work();
219  driver3->do_work();
220 
221  q_manager1.do_work();
222  q_manager2.do_work();
223  q_manager3.do_work();
224 
225  mac2.do_work();
226  mac3.do_work();
227 
228  usleep(100000);
229 
230  if (received_message)
231  break;
232 
233  ++i;
234  }
235 
236  if (received_message)
237  {
238  std::cout << "all tests passed" << std::endl;
239  return 0;
240  }
241  else
242  {
243  std::cout << "never received message" << std::endl;
244  return 1;
245  }
246 }
247 
248 void handle_receive1(const google::protobuf::Message& msg) { assert(false); }
249 
250 void handle_receive2(const google::protobuf::Message& msg) { assert(false); }
251 
252 void handle_receive3(const google::protobuf::Message& msg)
253 {
254  std::cout << "Received at 3.1: " << msg.DebugString() << std::endl;
255  std::cout << "Original: " << in_msg.DebugString() << std::endl;
256  received_message = true;
257  assert(in_msg.SerializeAsString() == msg.SerializeAsString());
258 }
259 
260 void handle_modem_receive3(const protobuf::ModemTransmission& message)
261 {
264  dccl_cfg.set_crypto_passphrase("my_passphrase2!");
265  dccl->set_cfg(dccl_cfg);
266 }
provides an API to the goby-acomms Queuing Library.
Definition: queue_manager.h:49
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
Definition: flex_ostream.h:67
static DCCLCodec * get()
DCCLCodec is a singleton class; use this to get a pointer to the class.
Definition: dccl.h:124
void startup(const protobuf::MACConfig &cfg)
Starts the MAC with given configuration.
Definition: mac_manager.cpp:65
boost::signals2::signal< void(const google::protobuf::Message &msg)> signal_receive
Signals when a DCCL message is received.
void do_work()
Allows the MAC timer to do its work. Does not block. If you prefer more control you can directly cont...
Definition: mac_manager.h:76
void handle_modem_receive(const protobuf::ModemTransmission &message)
Receive incoming data from the modem.
ReturnType goby_time()
Returns current UTC time as a boost::posix_time::ptime.
Definition: time.h:104
provides an API to the goby-acomms MAC library. MACManager is essentially a std::list<protobuf::Modem...
Definition: mac_manager.h:51
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...
void do_work()
Calculates which messages have expired and emits the goby::acomms::QueueManager::signal_expire as nec...
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