TraveSim Adapters  0.1
Protobuf adapters for TraveSim project
receiver.cpp
Go to the documentation of this file.
1 /**
2  * @file receiver.cpp
3  *
4  * @author Lucas Haug <lucas.haug@thuneratz.org>
5  * @author Lucas Schneider <lucas.schneider@thuneratz.org>
6  *
7  * @brief Receiver data using UDP
8  *
9  * @date 04/2021
10  *
11  * @copyright MIT License - Copyright (c) 2021 ThundeRatz
12  */
13 
14 #include <exception>
15 
17 
18 /*****************************************
19  * Private Constants
20  *****************************************/
21 
22 #define NO_FLAGS 0U
23 
24 #define INVALID_ENDPOINT boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0) // 0.0.0.0:0
25 
26 namespace travesim {
27 namespace udp {
28 /*****************************************
29  * Public Methods Bodies Definitions
30  *****************************************/
31 
32 Receiver::Receiver(const std::string receiver_address, const short receiver_port) {
33  this->set_receiver_endpoint(receiver_address, receiver_port);
34 
35  this->force_specific_source(false);
36 
37  this->socket = new boost::asio::ip::udp::socket(io_context);
38 };
39 
41  delete this->socket;
42 };
43 
44 size_t Receiver::receive(char* buffer, const size_t buffer_size) {
45  size_t bytes_received;
46  boost::system::error_code ec;
47  boost::asio::ip::udp::endpoint current_endpoint;
48 
49  bytes_received =
50  this->socket->receive_from(boost::asio::buffer(buffer, buffer_size), current_endpoint, NO_FLAGS, ec);
51 
52  this->validate_sender_endpoint(current_endpoint);
53 
54  switch (ec.value()) {
55  case boost::system::errc::success: {
56  /**
57  * @todo sender_endpoint loggin?
58  */
59  break;
60  }
61 
62  case boost::asio::error::would_block: {
63  bytes_received = 0;
64  break;
65  }
66 
67  default: {
68  throw boost::system::system_error(ec);
69  }
70  }
71 
72  return bytes_received;
73 };
74 
75 size_t Receiver::receive_latest(char* buffer, const size_t buffer_size) {
76  size_t bytes_received;
77  boost::system::error_code ec;
78  boost::asio::ip::udp::endpoint current_endpoint;
79 
80  do {
81  bytes_received =
82  this->socket->receive_from(boost::asio::buffer(buffer, buffer_size), current_endpoint, NO_FLAGS, ec);
83  } while (this->socket->available() > 0);
84 
85  this->validate_sender_endpoint(current_endpoint);
86 
87  switch (ec.value()) {
88  case boost::system::errc::success: {
89  /**
90  * @todo sender_endpoint loggin?
91  */
92  break;
93  }
94 
95  case boost::asio::error::would_block: {
96  bytes_received = 0;
97  break;
98  }
99 
100  default: {
101  throw boost::system::system_error(ec);
102  }
103  }
104 
105  return bytes_received;
106 };
107 
108 void Receiver::force_specific_source(bool specific_source) {
109  this->specific_source = specific_source;
110 };
111 
112 void Receiver::set_receiver_endpoint(const std::string receiver_address, const short receiver_port) {
113  const boost::asio::ip::address receiver_boost_addr = boost::asio::ip::address::from_string(receiver_address);
114  this->receiver_endpoint = boost::asio::ip::udp::endpoint(receiver_boost_addr, receiver_port);
115 };
116 
117 void Receiver::reset(void) {
119 
120  this->close_socket();
121  this->open_socket();
122 };
123 
124 /*****************************************
125  * Protected Methods Bodies Definitions
126  *****************************************/
127 
129  if (this->socket->is_open()) {
130  this->socket->close();
131  }
132 };
133 
134 /*****************************************
135  * Private Methods Bodies Definitions
136  *****************************************/
137 
138 inline void Receiver::validate_sender_endpoint(boost::asio::ip::udp::endpoint current_sender_endpoint) {
139  if (this->specific_source) {
140  if (this->sender_endpoint == INVALID_ENDPOINT) {
141  this->sender_endpoint = current_sender_endpoint;
142  } else if (this->sender_endpoint != current_sender_endpoint) {
143  if (current_sender_endpoint != INVALID_ENDPOINT) {
144  std::string error_msg = "Error in receiver. Any-source not enabled.";
145  throw std::runtime_error(error_msg);
146  }
147  }
148  }
149 };
150 } // namespace udp
151 } // namespace travesim
virtual void close_socket()
Close the socket.
Definition: receiver.cpp:128
boost::asio::ip::udp::socket * socket
Definition: receiver.hpp:88
void validate_sender_endpoint(boost::asio::ip::udp::endpoint current_sender_endpoint)
Validate whether the current sender endpoint matches the first sender endpoint when using specific so...
Definition: receiver.cpp:138
virtual void open_socket()=0
Open the socket with the desired options.
#define INVALID_ENDPOINT
Definition: receiver.cpp:24
void reset(void)
Reset the receiver.
Definition: receiver.cpp:117
boost::asio::ip::udp::endpoint receiver_endpoint
Definition: receiver.hpp:89
size_t receive_latest(char *buffer, const size_t buffer_size)
Receive the latest data using UDP.
Definition: receiver.cpp:75
Receiver data using UDP.
size_t receive(char *buffer, const size_t buffer_size)
Receive data using UDP.
Definition: receiver.cpp:44
#define NO_FLAGS
Definition: receiver.cpp:22
boost::asio::io_context io_context
Definition: receiver.hpp:119
void set_receiver_endpoint(const std::string receiver_address, const short receiver_port)
Set the receiver endpoint.
Definition: receiver.cpp:112
Receiver(const std::string receiver_address, const short receiver_port)
Construct a new Receiver object.
Definition: receiver.cpp:32
void force_specific_source(bool specific_source)
Set wheter to enable any source or source specific. True for specific source, false for any source,...
Definition: receiver.cpp:108
virtual ~Receiver()
Destroy the Receiver object.
Definition: receiver.cpp:40
boost::asio::ip::udp::endpoint sender_endpoint
Definition: receiver.hpp:121