From 079ef0f07dcf20242d90a3752f999e9ee50bba59 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 6 May 2024 18:58:09 +0200 Subject: [PATCH] Improve error handling of UDP connections --- docs/CHANGELOG.md | 4 + .../PVT/libs/monitor_ephemeris_udp_sink.cc | 40 +++++----- .../PVT/libs/monitor_pvt_udp_sink.cc | 20 ++--- .../rtl_tcp_signal_source_c.cc | 11 ++- src/core/libs/nav_message_udp_sink.cc | 36 ++++++--- src/core/monitor/gnss_synchro_udp_sink.cc | 24 +++--- src/core/receiver/tcp_cmd_interface.cc | 4 +- src/utils/nav-listener/main.cc | 7 ++ .../nav-listener/nav_msg_udp_listener.cc | 75 ++++++++++++------- src/utils/nav-listener/nav_msg_udp_listener.h | 1 + 10 files changed, 138 insertions(+), 84 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 473f7742b..18ef1d679 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -14,6 +14,10 @@ All notable changes to GNSS-SDR will be documented in this file. ## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next) +### Improvements in Interoperability: + +- Improved error handling in UDP connections. + ### Improvements in Portability: - Fix building against google-glog 0.7.0. diff --git a/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc index ca4ac6fbd..f9f48f0bb 100644 --- a/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc +++ b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc @@ -55,22 +55,24 @@ bool Monitor_Ephemeris_Udp_Sink::write_galileo_ephemeris(const std::shared_ptr #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif -Nav_Message_Udp_Sink::Nav_Message_Udp_Sink(const std::vector& addresses, const uint16_t& port) : socket{io_context} +Nav_Message_Udp_Sink::Nav_Message_Udp_Sink(const std::vector& addresses, const uint16_t& port) + : socket{io_context} { for (const auto& address : addresses) { @@ -35,22 +41,30 @@ bool Nav_Message_Udp_Sink::write_nav_message(const std::shared_ptr(endpoint.port()) << ": " << error.message(); + return false; + } + + if (socket.send(boost::asio::buffer(outbound_data)) == 0) // this can throw { return false; } } - catch (boost::system::system_error const& e) - { - return false; - } } + catch (const boost::system::system_error& e) + { + std::cerr << "Error sending navigation data: " << e.what() << '\n'; + return false; + } + return true; } diff --git a/src/core/monitor/gnss_synchro_udp_sink.cc b/src/core/monitor/gnss_synchro_udp_sink.cc index 84d484385..336f834cb 100644 --- a/src/core/monitor/gnss_synchro_udp_sink.cc +++ b/src/core/monitor/gnss_synchro_udp_sink.cc @@ -53,22 +53,24 @@ bool Gnss_Synchro_Udp_Sink::write_gnss_synchro(const std::vector& { outbound_data = serdes.createProtobuffer(stocks); } - for (const auto& endpoint : endpoints) - { - socket.open(endpoint.protocol(), error); - try + try + { + for (const auto& endpoint : endpoints) { - if (socket.send_to(boost::asio::buffer(outbound_data), endpoint) == 0) + socket.open(endpoint.protocol(), error); // NOLINT(bugprone-unused-return-value) + + if (socket.send_to(boost::asio::buffer(outbound_data), endpoint) == 0) // this can throw { - std::cerr << "Gnss_Synchro_Udp_Sink sent 0 bytes\n"; + return false; } } - catch (boost::system::system_error const& e) - { - std::cerr << e.what() << '\n'; - return false; - } } + catch (const boost::system::system_error& e) + { + std::cerr << "Error sending data: " << e.what() << '\n'; + return false; + } + return true; } diff --git a/src/core/receiver/tcp_cmd_interface.cc b/src/core/receiver/tcp_cmd_interface.cc index 1a47fb269..587aa99fb 100644 --- a/src/core/receiver/tcp_cmd_interface.cc +++ b/src/core/receiver/tcp_cmd_interface.cc @@ -323,10 +323,10 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) std::cout << "TcpCmdInterface: Telecommand TCP interface listening on port " << tcp_port << '\n'; boost::asio::ip::tcp::socket socket(context); - acceptor.accept(socket, not_throw); + acceptor.accept(socket, not_throw); // NOLINT(bugprone-unused-return-value) if (not_throw) { - std::cerr << "TcpCmdInterface: Error when binding the port in the socket\n"; + std::cerr << "TcpCmdInterface: Error when binding the port to the socket: " << not_throw.message() << '\n'; continue; } diff --git a/src/utils/nav-listener/main.cc b/src/utils/nav-listener/main.cc index 6fee013f7..f2b789497 100644 --- a/src/utils/nav-listener/main.cc +++ b/src/utils/nav-listener/main.cc @@ -31,6 +31,7 @@ int main(int argc, char *argv[]) unsigned short port = boost::lexical_cast(argv[1]); Nav_Msg_Udp_Listener udp_listener(port); + std::cout << "Listening on port " << static_cast(port) << ", press Control+C to exit ...\n"; while (true) { @@ -45,9 +46,15 @@ int main(int argc, char *argv[]) } } } + catch (boost::bad_lexical_cast &) + { + std::cerr << "Error: the argument " << argv[1] << " is not a valid port number.\n"; + return 1; + } catch (std::exception &e) { std::cerr << e.what() << '\n'; + return 1; } return 0; diff --git a/src/utils/nav-listener/nav_msg_udp_listener.cc b/src/utils/nav-listener/nav_msg_udp_listener.cc index 7961c8c8d..5a291b8ed 100644 --- a/src/utils/nav-listener/nav_msg_udp_listener.cc +++ b/src/utils/nav-listener/nav_msg_udp_listener.cc @@ -19,46 +19,67 @@ #include Nav_Msg_Udp_Listener::Nav_Msg_Udp_Listener(unsigned short port) - : socket{io_service}, endpoint{boost::asio::ip::udp::v4(), port} + : socket{io_service}, endpoint{boost::asio::ip::udp::v4(), port}, connected_socket(true) { - socket.open(endpoint.protocol(), error); // Open socket. - socket.bind(endpoint, error); // Bind the socket to the given local endpoint. + socket.open(endpoint.protocol(), error); // Open socket + if (error) + { + std::cerr << "Error opening socket: " << error.message() << '\n'; + connected_socket = false; + } + if (connected_socket) + { + socket.bind(endpoint, error); // Bind the socket to the given local endpoint. + if (error) + { + std::cerr << "Error binding socket: " << error.message() << '\n'; + connected_socket = false; + } + } } -/** - * !\brief blocking call to read nav_message from UDP port - * \param[out] message navigation message class to contain parsed output - * \return true if message parsed succesfully, false ow + +/* + * Blocking call to read nav_message from UDP port + * return true if message parsed succesfully, false ow */ bool Nav_Msg_Udp_Listener::receive_and_parse_nav_message(gnss_sdr::navMsg &message) { - char buff[8192]; // Buffer for storing the received data. + if (connected_socket) + { + char buff[8192]; // Buffer for storing the received data. - // This call will block until one or more bytes of data has been received. - int bytes = socket.receive(boost::asio::buffer(buff)); + // This call will block until one or more bytes of data has been received. + int bytes = socket.receive(boost::asio::buffer(buff)); - std::string data(&buff[0], bytes); - // Deserialize a stock of Nav_Msg objects from the binary string. - return message.ParseFromString(data); + std::string data(&buff[0], bytes); + // Deserialize a stock of Nav_Msg objects from the binary string. + return message.ParseFromString(data); + } + return false; } + /* - * !\brief prints navigation message content - * \param[in] message nav message to be printed + * Prints navigation message content + * param[in] message nav message to be printed */ void Nav_Msg_Udp_Listener::print_message(gnss_sdr::navMsg &message) const { - std::string system = message.system(); - std::string signal = message.signal(); - int prn = message.prn(); - int tow_at_current_symbol_ms = message.tow_at_current_symbol_ms(); - std::string nav_message = message.nav_message(); + if (connected_socket) + { + std::string system = message.system(); + std::string signal = message.signal(); + int prn = message.prn(); + int tow_at_current_symbol_ms = message.tow_at_current_symbol_ms(); + std::string nav_message = message.nav_message(); - std::cout << "\nNew Data received:\n"; - std::cout << "System: " << system << '\n'; - std::cout << "Signal: " << signal << '\n'; - std::cout << "PRN: " << prn << '\n'; - std::cout << "TOW of last symbol [ms]: " - << tow_at_current_symbol_ms << '\n'; - std::cout << "Nav message: " << nav_message << "\n\n"; + std::cout << "\nNew data received:\n"; + std::cout << "System: " << system << '\n'; + std::cout << "Signal: " << signal << '\n'; + std::cout << "PRN: " << prn << '\n'; + std::cout << "TOW of last symbol [ms]: " + << tow_at_current_symbol_ms << '\n'; + std::cout << "Nav message: " << nav_message << "\n\n"; + } } diff --git a/src/utils/nav-listener/nav_msg_udp_listener.h b/src/utils/nav-listener/nav_msg_udp_listener.h index c16654f40..6f70a042e 100644 --- a/src/utils/nav-listener/nav_msg_udp_listener.h +++ b/src/utils/nav-listener/nav_msg_udp_listener.h @@ -31,6 +31,7 @@ private: boost::asio::ip::udp::socket socket; boost::system::error_code error; boost::asio::ip::udp::endpoint endpoint; + bool connected_socket; }; #endif