1 #include "sol_manager.hpp" 2 3 #include "main.hpp" 4 #include "sol_context.hpp" 5 6 #include <sys/socket.h> 7 #include <sys/un.h> 8 9 #include <boost/asio/basic_stream_socket.hpp> 10 #include <boost/asio/io_context.hpp> 11 #include <boost/asio/local/stream_protocol.hpp> 12 #include <boost/asio/write.hpp> 13 #include <chrono> 14 #include <cmath> 15 #include <phosphor-logging/log.hpp> 16 17 namespace sol 18 { 19 20 using namespace phosphor::logging; 21 22 void Manager::initConsoleSocket() 23 { 24 // explicit length constructor for NUL-prefixed abstract path 25 std::string path(CONSOLE_SOCKET_PATH, CONSOLE_SOCKET_PATH_LEN); 26 boost::asio::local::stream_protocol::endpoint ep(path); 27 consoleSocket = 28 std::make_unique<boost::asio::local::stream_protocol::socket>(*io); 29 consoleSocket->connect(ep); 30 } 31 32 void Manager::consoleInputHandler() 33 { 34 boost::system::error_code ec; 35 boost::asio::socket_base::bytes_readable cmd(true); 36 consoleSocket->io_control(cmd, ec); 37 size_t readSize; 38 if (!ec) 39 { 40 readSize = cmd.get(); 41 } 42 else 43 { 44 log<level::ERR>("Reading ready count from host console socket failed:", 45 entry("EXCEPTION=%s", ec.message().c_str())); 46 return; 47 } 48 std::vector<uint8_t> buffer(readSize); 49 ec.clear(); 50 size_t readDataLen = 51 consoleSocket->read_some(boost::asio::buffer(buffer), ec); 52 if (ec) 53 { 54 log<level::ERR>("Reading from host console socket failed:", 55 entry("EXCEPTION=%s", ec.message().c_str())); 56 return; 57 } 58 59 // Update the Console buffer with data read from the socket 60 buffer.resize(readDataLen); 61 dataBuffer.write(buffer); 62 } 63 64 int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const 65 { 66 boost::system::error_code ec; 67 boost::asio::write(*consoleSocket, boost::asio::buffer(input), ec); 68 return ec.value(); 69 } 70 71 void Manager::startHostConsole() 72 { 73 if (!consoleSocket) 74 { 75 initConsoleSocket(); 76 } 77 consoleSocket->async_wait(boost::asio::socket_base::wait_read, 78 [this](const boost::system::error_code& ec) { 79 if (!ec) 80 { 81 consoleInputHandler(); 82 startHostConsole(); 83 } 84 }); 85 } 86 87 void Manager::stopHostConsole() 88 { 89 if (consoleSocket) 90 { 91 consoleSocket->cancel(); 92 consoleSocket.reset(); 93 } 94 } 95 96 void Manager::startPayloadInstance(uint8_t payloadInstance, 97 session::SessionID sessionID) 98 { 99 if (payloadMap.empty()) 100 { 101 startHostConsole(); 102 } 103 104 // Create the SOL Context data for payload instance 105 auto context = std::make_unique<Context>(io, retryCount, sendThreshold, 106 payloadInstance, sessionID); 107 108 payloadMap.emplace(payloadInstance, std::move(context)); 109 } 110 111 void Manager::stopPayloadInstance(uint8_t payloadInstance) 112 { 113 auto iter = payloadMap.find(payloadInstance); 114 if (iter == payloadMap.end()) 115 { 116 throw std::runtime_error("SOL Payload instance not found "); 117 } 118 119 payloadMap.erase(iter); 120 121 if (payloadMap.empty()) 122 { 123 stopHostConsole(); 124 125 dataBuffer.erase(dataBuffer.size()); 126 } 127 } 128 129 } // namespace sol 130