1 #include "sd_event_loop.hpp" 2 3 #include "main.hpp" 4 #include "message_handler.hpp" 5 6 #include <netinet/in.h> 7 #include <sys/ioctl.h> 8 #include <sys/socket.h> 9 #include <systemd/sd-daemon.h> 10 11 #include <boost/asio/io_context.hpp> 12 #include <phosphor-logging/log.hpp> 13 #include <sdbusplus/asio/sd_event.hpp> 14 15 namespace eventloop 16 { 17 using namespace phosphor::logging; 18 19 void EventLoop::handleRmcpPacket() 20 { 21 try 22 { 23 auto channelPtr = std::make_shared<udpsocket::Channel>(udpSocket); 24 25 // Initialize the Message Handler with the socket channel 26 auto msgHandler = std::make_shared<message::Handler>(channelPtr, io); 27 28 msgHandler->processIncoming(); 29 } 30 catch (const std::exception& e) 31 { 32 log<level::ERR>("Executing the IPMI message failed", 33 entry("EXCEPTION=%s", e.what())); 34 } 35 } 36 37 void EventLoop::startRmcpReceive() 38 { 39 udpSocket->async_wait(boost::asio::socket_base::wait_read, 40 [this](const boost::system::error_code& ec) { 41 if (!ec) 42 { 43 io->post([this]() { startRmcpReceive(); }); 44 handleRmcpPacket(); 45 } 46 }); 47 } 48 49 int EventLoop::startEventLoop() 50 { 51 // set up boost::asio signal handling 52 boost::asio::signal_set signals(*io, SIGINT, SIGTERM); 53 signals.async_wait( 54 [this](const boost::system::error_code& error, int signalNumber) { 55 udpSocket->cancel(); 56 udpSocket->close(); 57 io->stop(); 58 }); 59 60 // Create our own socket if SysD did not supply one. 61 int listensFdCount = sd_listen_fds(0); 62 if (listensFdCount == 1) 63 { 64 if (sd_is_socket(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_DGRAM, -1)) 65 { 66 udpSocket = std::make_shared<boost::asio::ip::udp::socket>( 67 *io, boost::asio::ip::udp::v6(), SD_LISTEN_FDS_START); 68 } 69 } 70 else if (listensFdCount > 1) 71 { 72 log<level::ERR>("Too many file descriptors received"); 73 return EXIT_FAILURE; 74 } 75 if (!udpSocket) 76 { 77 udpSocket = std::make_shared<boost::asio::ip::udp::socket>( 78 *io, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v6(), 79 IPMI_STD_PORT)); 80 if (!udpSocket) 81 { 82 log<level::ERR>("Failed to start listening on RMCP socket"); 83 return EXIT_FAILURE; 84 } 85 } 86 startRmcpReceive(); 87 88 io->run(); 89 90 return EXIT_SUCCESS; 91 } 92 93 } // namespace eventloop 94