From 76e7f0f79c908bf7d0a447ea643dbcdde8f064d2 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 21 Mar 2015 14:30:09 +0100 Subject: Start big refactoring Multiplexer in separate object Replace pointers by shared_ptr Switch to C++11 --- src/RemoteControl.cpp | 134 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 46 deletions(-) (limited to 'src/RemoteControl.cpp') diff --git a/src/RemoteControl.cpp b/src/RemoteControl.cpp index e46bc8d..723ba9b 100644 --- a/src/RemoteControl.cpp +++ b/src/RemoteControl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "Log.h" @@ -35,6 +36,12 @@ using boost::asio::ip::tcp; using namespace std; +RemoteControllerTelnet::~RemoteControllerTelnet() +{ + m_running = false; + m_io_service.stop(); + m_child_thread.join(); +} void RemoteControllerTelnet::restart() { @@ -47,85 +54,120 @@ void RemoteControllerTelnet::restart() // thread. void RemoteControllerTelnet::restart_thread(long) { + etiLog.level(warn) << "RC: Restart Telnet server"; + m_running = false; + m_io_service.stop(); - if (m_port) { - m_child_thread.interrupt(); - m_child_thread.join(); - } + m_child_thread.join(); m_child_thread = boost::thread(&RemoteControllerTelnet::process, this, 0); } -void RemoteControllerTelnet::process(long) +void RemoteControllerTelnet::handle_accept( + const boost::system::error_code& boost_error, + boost::shared_ptr< boost::asio::ip::tcp::socket > socket, + boost::asio::ip::tcp::acceptor& acceptor) { - m_welcome = "ODR-DabMux Remote Control CLI\nWrite 'help' for help.\n**********\n"; - m_prompt = "> "; + + const std::string welcome = "ODR-DabMux Remote Control CLI\n" + "Write 'help' for help.\n" + "**********\n"; + const std::string prompt = "> "; std::string in_message; size_t length; - try { - boost::asio::io_service io_service; - tcp::acceptor acceptor(io_service, tcp::endpoint( - boost::asio::ip::address::from_string("127.0.0.1"), m_port) ); - - while (m_running) { - in_message = ""; + if (boost_error) + { + etiLog.level(error) << "RC: Error accepting connection"; + return; + } - tcp::socket socket(io_service); + try { + etiLog.level(info) << "RC: Accepted"; - acceptor.accept(socket); + boost::system::error_code ignored_error; - boost::system::error_code ignored_error; + boost::asio::write(*socket, boost::asio::buffer(welcome), + boost::asio::transfer_all(), + ignored_error); - boost::asio::write(socket, boost::asio::buffer(m_welcome), + while (m_running && in_message != "quit") { + boost::asio::write(*socket, boost::asio::buffer(prompt), boost::asio::transfer_all(), ignored_error); - while (m_running && in_message != "quit") { - boost::asio::write(socket, boost::asio::buffer(m_prompt), - boost::asio::transfer_all(), - ignored_error); - - in_message = ""; + in_message = ""; - boost::asio::streambuf buffer; - length = boost::asio::read_until( socket, buffer, "\n", ignored_error); + boost::asio::streambuf buffer; + length = boost::asio::read_until(*socket, buffer, "\n", ignored_error); - std::istream str(&buffer); - std::getline(str, in_message); + std::istream str(&buffer); + std::getline(str, in_message); - if (length == 0) { - etiLog.level(info) << "RC: Connection terminated"; - break; - } + if (length == 0) { + etiLog.level(info) << "RC: Connection terminated"; + break; + } - while (in_message.length() > 0 && - (in_message[in_message.length()-1] == '\r' || - in_message[in_message.length()-1] == '\n')) { - in_message.erase(in_message.length()-1, 1); - } + while (in_message.length() > 0 && + (in_message[in_message.length()-1] == '\r' || + in_message[in_message.length()-1] == '\n')) { + in_message.erase(in_message.length()-1, 1); + } - if (in_message.length() == 0) { - continue; - } + if (in_message.length() == 0) { + continue; + } - etiLog.level(info) << "RC: Got message '" << in_message << "'"; + etiLog.level(info) << "RC: Got message '" << in_message << "'"; - dispatch_command(socket, in_message); - } - etiLog.level(info) << "RC: Closing socket"; - socket.close(); + dispatch_command(*socket, in_message); } + etiLog.level(info) << "RC: Closing socket"; + socket->close(); } catch (std::exception& e) { etiLog.level(error) << "Remote control caught exception: " << e.what(); - m_fault = true; } } +void RemoteControllerTelnet::process(long) +{ + m_running = true; + + while (m_running) { + m_io_service.reset(); + + tcp::acceptor acceptor(m_io_service, tcp::endpoint( + boost::asio::ip::address::from_string("127.0.0.1"), m_port) ); + + + // Add a job to start accepting connections. + boost::shared_ptr socket( + new tcp::socket(acceptor.get_io_service())); + + // Add an accept call to the service. This will prevent io_service::run() + // from returning. + etiLog.level(warn) << "RC: Waiting on connection"; + acceptor.async_accept(*socket, + boost::bind(&RemoteControllerTelnet::handle_accept, + this, + boost::asio::placeholders::error, + socket, + boost::ref(acceptor))); + + // Process event loop. + m_io_service.run(); + } + + etiLog.level(warn) << "RC: Leaving"; + m_fault = true; +} + + void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string command) { vector cmd = tokenise_(command); -- cgit v1.2.3