11 #include "common/logger.h"
19 : local_ip_address_{local_ip_address},
20 local_port_num_{local_port_num},
22 udp_socket_{io_context_},
27 port_type_{port_type},
28 udp_handler_read_{std::move(udp_handler_read)},
31 thread_ = std::thread([
this]() {
32 std::unique_lock<std::mutex> lck(
mutex_);
60 if (ec.value() == boost::system::errc::success) {
62 boost::asio::socket_base::broadcast broadcast_option(
true);
65 boost::asio::socket_base::reuse_address reuse_address_option(
true);
70 udp_socket_.bind(Udp::endpoint(boost::asio::ip::address_v4::any(), 13400), ec);
76 if (ec.value() == boost::system::errc::success) {
77 Udp::endpoint endpoint{
udp_socket_.local_endpoint()};
79 __FILE__, __LINE__, __func__, [endpoint](std::stringstream &msg) {
80 msg <<
"Udp Socket Opened and bound to "
81 <<
"<" << endpoint.address().to_string() <<
"," << endpoint.port() <<
">";
86 std::lock_guard<std::mutex> lock{
mutex_};
94 result.EmplaceValue();
98 __FILE__, __LINE__, __func__,
99 [ec](std::stringstream &msg) { msg <<
"Udp Socket Bind failed with message: " << ec.message(); });
103 __FILE__, __LINE__, __func__,
104 [ec](std::stringstream &msg) { msg <<
"Udp Socket Opening failed with error: " << ec.message(); });
114 boost::asio::buffer(udp_message->GetTxBuffer(), std::size_t(udp_message->GetTxBuffer().size())),
115 Udp::endpoint{UdpIpAddress::from_string(std::string{udp_message->GetHostIpAddress()}),
116 udp_message->GetHostPortNumber()})};
118 if (send_size == udp_message->GetTxBuffer().size()) {
120 Udp::endpoint endpoint{
udp_socket_.local_endpoint()};
122 __FILE__, __LINE__, __func__, [&udp_message, endpoint](std::stringstream &msg) {
123 msg <<
"Udp message sent : "
124 <<
"<" << endpoint.address().to_string() <<
"," << endpoint.port() <<
">"
126 <<
"<" << udp_message->GetHostIpAddress() <<
"," << udp_message->GetHostPortNumber() <<
">";
128 result.EmplaceValue();
134 }
catch (boost::system::system_error
const &ec) {
135 UdpErrorCodeType error = ec.code();
136 std::cerr << error.message() <<
"\n";
138 __FILE__, __LINE__, __func__, [error, &udp_message](std::stringstream &msg) {
139 msg <<
"Udp message sending to "
140 <<
"<" << udp_message->GetHostIpAddress() <<
"> "
141 <<
"failed with error: " << error.message();
158 void UdpClientSocket::HandleMessage(
const UdpErrorCodeType &error, std::size_t total_bytes_received) {
160 if (error.value() == boost::system::errc::success) {
161 if (local_ip_address_ != remote_endpoint_.address().to_string()) {
163 received_data.reserve(total_bytes_received);
165 received_data.insert(received_data.begin(), rx_buffer_.begin(), rx_buffer_.begin() + total_bytes_received);
167 UdpMessagePtr udp_rx_message{std::make_unique<UdpMessage>(remote_endpoint_.address().to_string(),
168 remote_endpoint_.port(), std::move(received_data))};
171 __FILE__, __LINE__, __func__, [
this, &udp_rx_message](std::stringstream &msg) {
172 msg <<
"Udp Message received: "
173 <<
"<" << udp_rx_message->GetHostIpAddress() <<
"," << udp_rx_message->GetHostPortNumber() <<
">"
175 <<
"<" << local_ip_address_ <<
"," << local_port_num_ <<
">";
179 udp_handler_read_(std::move(udp_rx_message));
181 udp_socket_.async_receive_from(boost::asio::buffer(rx_buffer_), remote_endpoint_,
182 [
this](
const UdpErrorCodeType &error_received, std::size_t bytes_received) {
183 HandleMessage(error_received, bytes_received);
186 Udp::endpoint endpoint_{remote_endpoint_};
188 __FILE__, __LINE__, __func__, [endpoint_,
this](std::stringstream &msg) {
189 msg <<
"Udp Message received from "
190 <<
"<" << endpoint_.address().to_string() <<
"," << endpoint_.port() <<
">"
191 <<
" ignored as received by self ip"
192 <<
" <" << local_ip_address_ <<
">";
196 if (error.value() != boost::asio::error::operation_aborted) {
198 __FILE__, __LINE__, __func__, [error,
this](std::stringstream &msg) {
199 msg <<
"<" << local_ip_address_ <<
">: "
200 <<
"Remote Disconnected with undefined error: " << error.message();
static auto GetLibBoostLogger() noexcept -> LibBoostLogger &
std::atomic_bool running_
Flag to start the thread.
std::atomic_bool exit_request_
Flag to terminate the thread.
virtual ~UdpClientSocket()
Destruct an instance of UdpClientSocket.
void HandleMessage(const UdpErrorCodeType &error, std::size_t bytes_received)
Function to handle the reception of tcp message.
Udp::endpoint remote_endpoint_
Store the remote endpoint.
std::function< void(UdpMessagePtr)> UdpHandlerRead
Udp function template used for reception.
PortType port_type_
Store the port type - broadcast / unicast.
PortType
Type of udp port to be used underneath.
std::string local_ip_address_
Store local ip address.
std::condition_variable cond_var_
Conditional variable to block the thread.
boost::system::error_code UdpErrorCodeType
Type alias for udp error codes.
UdpSocket udp_socket_
Store tcp socket.
core_type::Result< void, UdpErrorCode > Transmit(UdpMessageConstPtr udp_message)
Function to trigger transmission.
std::thread thread_
The thread itself.
std::uint16_t local_port_num_
Store local port number.
boost::asio::io_context io_context_
boost io context
std::array< std::uint8_t, kDoipUdpResSize > rx_buffer_
Reception buffer needed for async reception of udp data.
std::mutex mutex_
mutex to lock critical section
core_type::Result< void, UdpErrorCode > Open()
Function to Open the socket.
UdpClientSocket(std::string_view local_ip_address, std::uint16_t local_port_num, PortType port_type, UdpHandlerRead udp_handler_read)
Constructs an instance of UdpClientSocket.
std::vector< uint8_t > BufferType
Type alias for underlying buffer.
Class type to contains a value (of type ValueType), or an error (of type ErrorType)
void EmplaceValue(Args &&...args) noexcept
Put a new value into this instance, constructed in-place from the given arguments.
std::unique_ptr< const UdpMessage > UdpMessageConstPtr
The unique pointer to const UdpMessage.
std::unique_ptr< UdpMessage > UdpMessagePtr
The unique pointer to UdpMessage.