From 966d935fbc2ac50b8b6b6619b6b018b337b1ef0e Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 23 Oct 2018 16:54:06 +0200 Subject: [PATCH] Adding the restart telecommand functionality by using external helper startup script --- src/core/receiver/control_thread.cc | 26 ++++++++-- src/core/receiver/control_thread.h | 3 +- src/core/receiver/tcp_cmd_interface.cc | 71 ++++++++++++++++++-------- src/core/receiver/tcp_cmd_interface.h | 21 +++++--- src/main/main.cc | 5 +- src/utils/scripts/gnss-sdr-harness.sh | 10 ++++ 6 files changed, 103 insertions(+), 33 deletions(-) create mode 100755 src/utils/scripts/gnss-sdr-harness.sh diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 1ee965920..ff4cd82c7 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -80,6 +80,7 @@ ControlThread::ControlThread() configuration_ = std::make_shared(FLAGS_c); } delete_configuration_ = false; + restart_ = false; init(); } @@ -115,7 +116,7 @@ void ControlThread::telecommand_listener() * while (flowgraph_->running() && !stop)_{ * 3- Read control messages and process them } */ -void ControlThread::run() +int ControlThread::run() { // Connect the flowgraph try @@ -125,7 +126,7 @@ void ControlThread::run() catch (const std::exception &e) { LOG(ERROR) << e.what(); - return; + return 0; } if (flowgraph_->connected()) { @@ -134,7 +135,7 @@ void ControlThread::run() else { LOG(ERROR) << "Unable to connect flowgraph"; - return; + return 0; } // Start the flowgraph flowgraph_->start(); @@ -145,7 +146,7 @@ void ControlThread::run() else { LOG(ERROR) << "Unable to start flowgraph"; - return; + return 0; } //launch GNSS assistance process AFTER the flowgraph is running because the GNURadio asynchronous queues must be already running to transport msgs @@ -189,6 +190,15 @@ void ControlThread::run() #endif LOG(INFO) << "Flowgraph stopped"; + + if (restart_) + { + return 42; //signal the gnss-sdr-harness.sh to restart the receiver program + } + else + { + return 0; //normal shutdown + } } @@ -200,6 +210,7 @@ void ControlThread::set_control_queue(gr::msg_queue::sptr control_queue) return; } control_queue_ = control_queue; + cmd_interface_.set_msg_queue(control_queue_); } @@ -602,6 +613,7 @@ void ControlThread::init() { // Instantiates a control queue, a GNSS flowgraph, and a control message factory control_queue_ = gr::msg_queue::make(0); + cmd_interface_.set_msg_queue(control_queue_); //set also the queue pointer for the telecommand thread try { flowgraph_ = std::make_shared(configuration_, control_queue_); @@ -668,6 +680,12 @@ void ControlThread::apply_action(unsigned int what) stop_ = true; applied_actions_++; break; + case 1: + DLOG(INFO) << "Received action RESTART"; + stop_ = true; + restart_ = true; + applied_actions_++; + break; default: DLOG(INFO) << "Unrecognized action."; break; diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index 3c67595c6..e8e62b5fe 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -83,7 +83,7 @@ public: * * - Read control messages and process them; } */ - void run(); + int run(); /*! * \brief Sets the control_queue @@ -155,6 +155,7 @@ private: std::shared_ptr control_message_factory_; std::shared_ptr>> control_messages_; bool stop_; + bool restart_; bool delete_configuration_; unsigned int processed_control_messages_; unsigned int applied_actions_; diff --git a/src/core/receiver/tcp_cmd_interface.cc b/src/core/receiver/tcp_cmd_interface.cc index 76144d297..c59b96224 100644 --- a/src/core/receiver/tcp_cmd_interface.cc +++ b/src/core/receiver/tcp_cmd_interface.cc @@ -30,8 +30,27 @@ */ #include "tcp_cmd_interface.h" +#include "control_message_factory.h" +#include +std::string TcpCmdInterface::reset(const std::vector &commandLine) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(200, 1)); //send the restart message (who=200,what=1) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + + return response; +} + std::string TcpCmdInterface::stop(const std::vector &commandLine) { std::string response; @@ -78,21 +97,28 @@ std::string TcpCmdInterface::set_ch_satellite(const std::vector &co void TcpCmdInterface::register_functions() { - functions["status"] = status; - functions["stop"] = stop; - functions["assistedstart"] = assistedstart; - functions["warmstart"] = warmstart; - functions["coldstart"] = coldstart; - functions["set_ch_satellite"] = set_ch_satellite; + functions["status"] = std::bind(&TcpCmdInterface::status, this, std::placeholders::_1); + functions["stop"] = std::bind(&TcpCmdInterface::stop, this, std::placeholders::_1); + functions["reset"] = std::bind(&TcpCmdInterface::reset, this, std::placeholders::_1); + functions["assistedstart"] = std::bind(&TcpCmdInterface::assistedstart, this, std::placeholders::_1); + functions["warmstart"] = std::bind(&TcpCmdInterface::warmstart, this, std::placeholders::_1); + functions["coldstart"] = std::bind(&TcpCmdInterface::coldstart, this, std::placeholders::_1); + functions["set_ch_satellite"] = std::bind(&TcpCmdInterface::set_ch_satellite, this, std::placeholders::_1); } TcpCmdInterface::TcpCmdInterface() { register_functions(); + keep_running_ = true; + control_queue_ = nullptr; } +void TcpCmdInterface::set_msg_queue(gr::msg_queue::sptr control_queue) +{ + control_queue_ = control_queue; +} void TcpCmdInterface::run_cmd_server(int tcp_port) { // Get the port from the parameters @@ -106,18 +132,18 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) try { boost::asio::ip::tcp::acceptor acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)); - bool keep_running = true; - while (keep_running) + + while (keep_running_) { try { - std::cout << "Telecommand TCP interface listening on port " << tcp_port << std::endl; + std::cout << "TcpCmdInterface: Telecommand TCP interface listening on port " << tcp_port << std::endl; boost::asio::ip::tcp::socket socket(service); acceptor.accept(socket, not_throw); if (not_throw) { - std::cerr << "Error when binding the port in the socket" << std::endl; + std::cout << "TcpCmdInterface: Error when binding the port in the socket" << std::endl; continue; } @@ -127,12 +153,10 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) { std::string response; boost::asio::streambuf b; - boost::asio::read_until(socket, b, '\n'); + boost::asio::read_until(socket, b, '\n', error); std::istream is(&b); std::string line; std::getline(is, line); - std::cout << "received command: " << line << std::endl; - std::istringstream iss(line); std::vector cmd_vector(std::istream_iterator{iss}, std::istream_iterator()); @@ -141,7 +165,14 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) { try { - response = functions[cmd_vector.at(0)](cmd_vector); + if (cmd_vector.at(0).compare("exit") == 0) + { + error = boost::asio::error::eof; + } + else + { + response = functions[cmd_vector.at(0)](cmd_vector); + } } catch (const std::exception &ex) { @@ -157,19 +188,19 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) socket.write_some(boost::asio::buffer(response), not_throw); if (not_throw) { - std::cerr << "Error sending(" << not_throw.value() << "): " << not_throw.message() << std::endl; + std::cout << "Error sending(" << not_throw.value() << "): " << not_throw.message() << std::endl; break; } } - while (!error); // && error != boost::asio::error::eof); + while (error != boost::asio::error::eof); if (error == boost::asio::error::eof) { - std::cout << "EOF detected\n"; + std::cout << "TcpCmdInterface: EOF detected\n"; } else { - std::cout << "error: " << error << std::endl; + std::cout << "TcpCmdInterface unexpected error: " << error << std::endl; } // Close socket @@ -177,11 +208,11 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) } catch (const boost::exception &e) { - std::cout << "Boost exception " << std::endl; + std::cout << "TcpCmdInterface: Boost exception " << std::endl; } catch (const std::exception &ex) { - std::cout << "Exception " << ex.what() << std::endl; + std::cout << "TcpCmdInterface: Exception " << ex.what() << std::endl; } } } diff --git a/src/core/receiver/tcp_cmd_interface.h b/src/core/receiver/tcp_cmd_interface.h index 5ffc44cb1..a6a9c297c 100644 --- a/src/core/receiver/tcp_cmd_interface.h +++ b/src/core/receiver/tcp_cmd_interface.h @@ -38,7 +38,10 @@ #include #include #include +#include #include +#include +#include class TcpCmdInterface @@ -47,18 +50,24 @@ public: TcpCmdInterface(); virtual ~TcpCmdInterface(); void run_cmd_server(int tcp_port); + void set_msg_queue(gr::msg_queue::sptr control_queue); + private: std::unordered_map &)>> functions; - static std::string status(const std::vector &commandLine); - static std::string stop(const std::vector &commandLine); - static std::string assistedstart(const std::vector &commandLine); - static std::string warmstart(const std::vector &commandLine); - static std::string coldstart(const std::vector &commandLine); - static std::string set_ch_satellite(const std::vector &commandLine); + std::string status(const std::vector &commandLine); + std::string reset(const std::vector &commandLine); + std::string stop(const std::vector &commandLine); + std::string assistedstart(const std::vector &commandLine); + std::string warmstart(const std::vector &commandLine); + std::string coldstart(const std::vector &commandLine); + std::string set_ch_satellite(const std::vector &commandLine); void register_functions(); + + gr::msg_queue::sptr control_queue_; + bool keep_running_; }; #endif /* GNSS_SDR_TCPCMDINTERFACE_H_ */ diff --git a/src/main/main.cc b/src/main/main.cc index d64f9bab6..9b3680115 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -135,9 +135,10 @@ int main(int argc, char** argv) std::chrono::time_point start, end; start = std::chrono::system_clock::now(); + int return_code; try { - control_thread->run(); + return_code = control_thread->run(); } catch (const boost::exception& e) { @@ -189,5 +190,5 @@ int main(int argc, char** argv) google::ShutDownCommandLineFlags(); std::cout << "GNSS-SDR program ended." << std::endl; - return 0; + return return_code; } diff --git a/src/utils/scripts/gnss-sdr-harness.sh b/src/utils/scripts/gnss-sdr-harness.sh new file mode 100755 index 000000000..b025bb07b --- /dev/null +++ b/src/utils/scripts/gnss-sdr-harness.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# GNSS-SDR shell script that enables the remote GNSS-SDR restart telecommand +# usage: ./gnss-sdr-harness.sh ./gnss-sdr -c config_file.conf +echo $@ +$@ +while [ $? -eq 42 ] +do + echo "restarting GNSS-SDR..." + $@ +done