udp_board.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Daniel Koch, BYU MAGICC Lab.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * * Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
38 #include <iostream>
39 
40 using boost::asio::ip::udp;
41 
42 namespace rosflight_firmware
43 {
44 UDPBoard::UDPBoard(std::string bind_host, uint16_t bind_port, std::string remote_host, uint16_t remote_port) :
45  bind_host_(bind_host),
46  bind_port_(bind_port),
47  remote_host_(remote_host),
48  remote_port_(remote_port),
49  io_service_(),
50  socket_(io_service_),
51  write_in_progress_(false)
52 {
53 }
54 
56 {
57  MutexLock read_lock(read_mutex_);
58  MutexLock write_lock(write_mutex_);
59 
60  io_service_.stop();
61  socket_.close();
62 
63  if (io_thread_.joinable())
64  io_thread_.join();
65 }
66 
67 void UDPBoard::set_ports(std::string bind_host, uint16_t bind_port, std::string remote_host, uint16_t remote_port)
68 {
69  bind_host_ = bind_host;
70  bind_port_ = bind_port;
71  remote_host_ = remote_host;
72  remote_port_ = remote_port;
73 }
74 
75 void UDPBoard::serial_init(uint32_t baud_rate, uint32_t dev)
76 {
77  // can throw an uncaught boost::system::system_error exception
78  (void)dev;
79 
80  udp::resolver resolver(io_service_);
81 
82  bind_endpoint_ = *resolver.resolve({udp::v4(), bind_host_, ""});
84 
85  remote_endpoint_ = *resolver.resolve({udp::v4(), remote_host_, ""});
87 
88  socket_.open(udp::v4());
89  socket_.bind(bind_endpoint_);
90 
91  socket_.set_option(udp::socket::reuse_address(true));
92  socket_.set_option(udp::socket::send_buffer_size(1000 * MAVLINK_MAX_PACKET_LEN));
93  socket_.set_option(udp::socket::receive_buffer_size(1000 * MAVLINK_MAX_PACKET_LEN));
94 
95  async_read();
96  io_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_));
97 }
98 
100 
101 void UDPBoard::serial_write(const uint8_t *src, size_t len)
102 {
103  Buffer *buffer = new Buffer(src, len);
104 
105  {
106  MutexLock lock(write_mutex_);
107  write_queue_.push_back(buffer);
108  }
109 
110  async_write(true);
111 }
112 
114 {
115  MutexLock lock(read_mutex_);
116  return !read_queue_.empty();
117 }
118 
120 {
121  MutexLock lock(read_mutex_);
122 
123  if (read_queue_.empty())
124  return 0;
125 
126  Buffer *buffer = read_queue_.front();
127  uint8_t byte = buffer->consume_byte();
128 
129  if (buffer->empty())
130  {
131  read_queue_.pop_front();
132  delete buffer;
133  }
134  return byte;
135 }
136 
138 {
139  if (!socket_.is_open())
140  return;
141 
142  MutexLock lock(read_mutex_);
145  boost::asio::placeholders::bytes_transferred));
146 }
147 
148 void UDPBoard::async_read_end(const boost::system::error_code &error, size_t bytes_transferred)
149 {
150  if (!error)
151  {
152  MutexLock lock(read_mutex_);
153  read_queue_.push_back(new Buffer(read_buffer_, bytes_transferred));
154  }
155  async_read();
156 }
157 
158 void UDPBoard::async_write(bool check_write_state)
159 {
160  if (check_write_state && write_in_progress_)
161  return;
162 
163  MutexLock lock(write_mutex_);
164  if (write_queue_.empty())
165  return;
166 
167  write_in_progress_ = true;
168  Buffer *buffer = write_queue_.front();
169  socket_.async_send_to(boost::asio::buffer(buffer->dpos(), buffer->nbytes()), remote_endpoint_,
171  boost::asio::placeholders::bytes_transferred));
172 }
173 
174 void UDPBoard::async_write_end(const boost::system::error_code &error, size_t bytes_transferred)
175 {
176  if (!error)
177  {
178  MutexLock lock(write_mutex_);
179 
180  if (write_queue_.empty())
181  {
182  write_in_progress_ = false;
183  return;
184  }
185 
186  Buffer *buffer = write_queue_.front();
187  buffer->pos += bytes_transferred;
188  if (buffer->empty())
189  {
190  write_queue_.pop_front();
191  delete buffer;
192  }
193 
194  if (write_queue_.empty())
195  write_in_progress_ = false;
196  else
197  async_write(false);
198  }
199 }
200 
201 } // namespace rosflight_firmware
void serial_flush() override
Definition: udp_board.cpp:99
boost::asio::ip::udp::socket socket_
Definition: udp_board.h:111
std::list< Buffer * > write_queue_
Definition: udp_board.h:118
static volatile bool error
Definition: drv_i2c.c:92
void serial_init(uint32_t baud_rate, uint32_t dev) override
Definition: udp_board.cpp:75
void serial_write(const uint8_t *src, size_t len) override
Definition: udp_board.cpp:101
static uint8_t buffer[BMP280_DATA_FRAME_SIZE]
Definition: drv_bmp280.c:61
UDPBoard(std::string bind_host="localhost", uint16_t bind_port=14525, std::string remote_host="localhost", uint16_t remote_port=14520)
Definition: udp_board.cpp:44
boost::asio::ip::udp::endpoint bind_endpoint_
Definition: udp_board.h:112
boost::asio::ip::udp::endpoint remote_endpoint_
Definition: udp_board.h:113
void async_write(bool check_write_state)
Definition: udp_board.cpp:158
void async_read_end(const boost::system::error_code &error, size_t bytes_transferred)
Definition: udp_board.cpp:148
boost::lock_guard< boost::recursive_mutex > MutexLock
Definition: udp_board.h:91
boost::recursive_mutex write_mutex_
Definition: udp_board.h:106
uint16_t serial_bytes_available(void) override
Definition: udp_board.cpp:113
const uint8_t * dpos() const
Definition: udp_board.h:83
void set_ports(std::string bind_host, uint16_t bind_port, std::string remote_host, uint16_t remote_port)
Definition: udp_board.cpp:67
uint8_t serial_read(void) override
Definition: udp_board.cpp:119
boost::recursive_mutex read_mutex_
Definition: udp_board.h:107
boost::asio::io_service io_service_
Definition: udp_board.h:109
std::list< Buffer * > read_queue_
Definition: udp_board.h:116
void async_write_end(const boost::system::error_code &error, size_t bytes_transferred)
Definition: udp_board.cpp:174
uint8_t read_buffer_[MAVLINK_MAX_PACKET_LEN]
Definition: udp_board.h:115


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Apr 15 2021 05:07:49