23 #include "udp_driver.h" 25 #include "goby/acomms/modemdriver/driver_exception.h" 26 #include "goby/acomms/modemdriver/mm_driver.h" 27 #include "goby/common/logger.h" 28 #include "goby/util/binary.h" 31 using goby::util::hex_decode;
32 using goby::util::hex_encode;
36 const size_t UDP_MAX_PACKET_SIZE = 65507;
38 goby::acomms::UDPDriver::UDPDriver(boost::asio::io_service* io_service)
39 : io_service_(io_service), socket_(*io_service), receive_buffer_(UDP_MAX_PACKET_SIZE),
44 goby::acomms::UDPDriver::~UDPDriver() {}
51 socket_.open(boost::asio::ip::udp::v4());
52 socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), local.port()));
55 boost::asio::ip::udp::resolver resolver(*io_service_);
56 boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), remote.ip(),
57 goby::util::as<std::string>(remote.port()));
58 boost::asio::ip::udp::resolver::iterator endpoint_iterator = resolver.resolve(query);
59 receiver_ = *endpoint_iterator;
61 glog.is(DEBUG1) &&
glog << group(glog_out_group())
62 <<
"Receiver endpoint is: " << receiver_.address().to_string() <<
":" 63 << receiver_.port() << std::endl;
82 if (!msg.has_frame_start())
83 msg.set_frame_start(next_frame_);
85 msg.set_max_frame_bytes(driver_cfg_.GetExtension(UDPDriverConfig::max_frame_size));
88 glog.is(DEBUG1) &&
glog << group(glog_out_group())
89 <<
"After modification, initiating transmission with " << msg
92 next_frame_ += msg.frame_size();
94 if (!(msg.frame_size() == 0 || msg.frame(0).empty()))
102 if (msg.type() == protobuf::ModemTransmission::DATA && msg.ack_requested() &&
107 ack.set_type(goby::acomms::protobuf::ModemTransmission::ACK);
108 ack.set_src(msg.dest());
109 ack.set_dest(msg.src());
110 for (
int i = msg.frame_start(), n = msg.frame_size() + msg.frame_start(); i < n; ++i)
111 ack.add_acked_frame(i);
122 msg.SerializeToString(&bytes);
124 glog.is(DEBUG1) &&
glog << group(glog_out_group())
125 <<
"Sending hex: " << goby::util::hex_encode(bytes) << std::endl;
128 raw_msg.set_raw(bytes);
131 socket_.async_send_to(boost::asio::buffer(bytes), receiver_,
132 boost::bind(&UDPDriver::send_complete,
this, _1, _2));
135 void goby::acomms::UDPDriver::send_complete(
const boost::system::error_code& error,
136 std::size_t bytes_transferred)
140 glog.is(DEBUG1) &&
glog << group(glog_out_group()) << warn
141 <<
"Send error: " << error.message() << std::endl;
145 glog.is(DEBUG1) &&
glog << group(glog_out_group()) <<
"Sent " << bytes_transferred <<
" bytes." 149 void goby::acomms::UDPDriver::start_receive()
151 socket_.async_receive_from(boost::asio::buffer(receive_buffer_), sender_,
152 boost::bind(&UDPDriver::receive_complete,
this, _1, _2));
155 void goby::acomms::UDPDriver::receive_complete(
const boost::system::error_code& error,
156 std::size_t bytes_transferred)
160 glog.is(DEBUG1) &&
glog << group(glog_in_group()) << warn
161 <<
"Receive error: " << error.message() << std::endl;
167 raw_msg.set_raw(std::string(&receive_buffer_[0], bytes_transferred));
170 glog.is(DEBUG1) &&
glog << group(glog_in_group()) <<
"Received " << bytes_transferred
171 <<
" bytes from " << sender_.address().to_string() <<
":" 172 << sender_.port() << std::endl;
175 msg.ParseFromArray(&receive_buffer_[0], bytes_transferred);
176 receive_message(msg);
void handle_initiate_transmission(const protobuf::ModemTransmission &m)
Virtual initiate_transmission method. Typically connected to MACManager::signal_initiate_transmission...
boost::signals2::signal< void(const protobuf::ModemRaw &msg)> signal_raw_incoming
Called after any message is received from the modem by the driver. Used by the MACManager for auto-di...
ReturnType goby_time()
Returns current UTC time as a boost::posix_time::ptime.
boost::signals2::signal< void(const protobuf::ModemTransmission &message)> signal_receive
Called when a binary data transmission is received from the modem.
const int BROADCAST_ID
special modem id for the broadcast destination - no one is assigned this address. Analogous to 192...
void shutdown()
Shuts down the modem driver.
common::FlexOstream glog
Access the Goby logger through this object.
boost::signals2::signal< void(const protobuf::ModemRaw &msg)> signal_raw_outgoing
Called after any message is sent from the driver to the modem. Useful for higher level analysis and d...
boost::signals2::signal< void(protobuf::ModemTransmission *msg)> signal_data_request
Called when the modem or modem driver needs data to send. The returned data should be stored in Modem...
void do_work()
Allows the modem driver to do its work.
boost::signals2::signal< void(protobuf::ModemTransmission *msg_request)> signal_modify_transmission
Called before the modem driver begins processing a transmission. This allows a third party to modify ...
void startup(const protobuf::DriverConfig &cfg)
Starts the modem driver. Must be called before poll().