blob: 5be974a20dc7c9f28e1324407ad63cf85a0bcc97 [file] [log] [blame]
Vernon Mauery9e801a22018-10-12 13:20:49 -07001#include "sd_event_loop.hpp"
2
3#include "main.hpp"
4#include "message_handler.hpp"
5
Dave Cobbley2c15f0c2017-11-13 16:19:09 -08006#include <netinet/in.h>
Tom Joseph7fd26dd2017-03-14 15:26:26 +05307#include <sys/ioctl.h>
Dave Cobbley2c15f0c2017-11-13 16:19:09 -08008#include <sys/socket.h>
Tom Joseph7fd26dd2017-03-14 15:26:26 +05309#include <systemd/sd-daemon.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -070010
Vernon Mauerycbccb052018-10-24 13:52:22 -070011#include <boost/asio/io_context.hpp>
Tom Joseph7fd26dd2017-03-14 15:26:26 +053012#include <phosphor-logging/log.hpp>
Vernon Mauerycbccb052018-10-24 13:52:22 -070013#include <sdbusplus/asio/sd_event.hpp>
Tom Joseph7fd26dd2017-03-14 15:26:26 +053014
15namespace eventloop
16{
17using namespace phosphor::logging;
18
Vernon Mauery7a0142c2018-11-09 08:38:16 -080019void EventLoop::handleRmcpPacket()
Tom Joseph7fd26dd2017-03-14 15:26:26 +053020{
Tom Joseph7fd26dd2017-03-14 15:26:26 +053021 try
22 {
Vernon Mauery7a0142c2018-11-09 08:38:16 -080023 auto channelPtr = std::make_shared<udpsocket::Channel>(udpSocket);
Tom Joseph7fd26dd2017-03-14 15:26:26 +053024
25 // Initialize the Message Handler with the socket channel
Vernon Mauery7a0142c2018-11-09 08:38:16 -080026 auto msgHandler = std::make_shared<message::Handler>(channelPtr);
Tom Joseph7fd26dd2017-03-14 15:26:26 +053027
Tom Joseph7fd26dd2017-03-14 15:26:26 +053028 // Read the incoming IPMI packet
Vernon Mauery7a0142c2018-11-09 08:38:16 -080029 std::shared_ptr<message::Message> inMessage(msgHandler->receive());
Tom Joseph7fd26dd2017-03-14 15:26:26 +053030 if (inMessage == nullptr)
31 {
Vernon Mauery7a0142c2018-11-09 08:38:16 -080032 return;
Tom Joseph7fd26dd2017-03-14 15:26:26 +053033 }
34
35 // Execute the Command
Vernon Mauery7a0142c2018-11-09 08:38:16 -080036 std::shared_ptr<message::Message> outMessage =
37 msgHandler->executeCommand(inMessage);
Tom Joseph7fd26dd2017-03-14 15:26:26 +053038 if (outMessage == nullptr)
39 {
Vernon Mauery7a0142c2018-11-09 08:38:16 -080040 return;
Tom Joseph7fd26dd2017-03-14 15:26:26 +053041 }
Tom Joseph7fd26dd2017-03-14 15:26:26 +053042 // Send the response IPMI Message
Vernon Mauery7a0142c2018-11-09 08:38:16 -080043 msgHandler->send(outMessage);
Tom Joseph7fd26dd2017-03-14 15:26:26 +053044 }
Vernon Mauery7a0142c2018-11-09 08:38:16 -080045 catch (const std::exception& e)
Tom Joseph7fd26dd2017-03-14 15:26:26 +053046 {
Vernon Mauery7a0142c2018-11-09 08:38:16 -080047 log<level::ERR>("Executing the IPMI message failed",
48 entry("EXCEPTION=%s", e.what()));
Tom Joseph7fd26dd2017-03-14 15:26:26 +053049 }
Vernon Mauery7a0142c2018-11-09 08:38:16 -080050}
Tom Joseph7fd26dd2017-03-14 15:26:26 +053051
Vernon Mauery7a0142c2018-11-09 08:38:16 -080052void EventLoop::startRmcpReceive()
53{
54 udpSocket->async_wait(boost::asio::socket_base::wait_read,
55 [this](const boost::system::error_code& ec) {
56 if (!ec)
57 {
58 io->post([this]() { startRmcpReceive(); });
59 handleRmcpPacket();
60 }
61 });
Tom Joseph7fd26dd2017-03-14 15:26:26 +053062}
63
Vernon Mauerycbccb052018-10-24 13:52:22 -070064int EventLoop::startEventLoop()
Tom Joseph7fd26dd2017-03-14 15:26:26 +053065{
Vernon Mauerycbccb052018-10-24 13:52:22 -070066 sdbusplus::asio::sd_event_wrapper sdEvents(*io);
67 event = sdEvents.get();
Marri Devender Rao3ecf0a12017-07-13 08:07:22 -050068
Vernon Mauery22c8a212018-10-24 14:51:23 -070069 // set up boost::asio signal handling
70 boost::asio::signal_set signals(*io, SIGINT, SIGTERM);
Vernon Mauery7a0142c2018-11-09 08:38:16 -080071 signals.async_wait(
72 [this](const boost::system::error_code& error, int signalNumber) {
73 udpSocket->cancel();
74 udpSocket->close();
75 io->stop();
76 });
Tom Joseph7fd26dd2017-03-14 15:26:26 +053077
Vernon Mauery9e801a22018-10-12 13:20:49 -070078 // Create our own socket if SysD did not supply one.
Vernon Mauery7a0142c2018-11-09 08:38:16 -080079 int listensFdCount = sd_listen_fds(0);
80 if (listensFdCount == 1)
Tom Joseph7fd26dd2017-03-14 15:26:26 +053081 {
Vernon Mauery7a0142c2018-11-09 08:38:16 -080082 if (sd_is_socket(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_DGRAM, -1))
83 {
84 udpSocket = std::make_shared<boost::asio::ip::udp::socket>(
85 *io, boost::asio::ip::udp::v6(), SD_LISTEN_FDS_START);
86 }
Dave Cobbley2c15f0c2017-11-13 16:19:09 -080087 }
Vernon Mauery7a0142c2018-11-09 08:38:16 -080088 else if (listensFdCount > 1)
Dave Cobbley2c15f0c2017-11-13 16:19:09 -080089 {
90 log<level::ERR>("Too many file descriptors received");
Vernon Mauerycbccb052018-10-24 13:52:22 -070091 return EXIT_FAILURE;
Tom Joseph7fd26dd2017-03-14 15:26:26 +053092 }
Vernon Mauery7a0142c2018-11-09 08:38:16 -080093 if (!udpSocket)
94 {
95 udpSocket = std::make_shared<boost::asio::ip::udp::socket>(
96 *io, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v6(),
97 IPMI_STD_PORT));
98 if (!udpSocket)
99 {
100 log<level::ERR>("Failed to start listening on RMCP socket");
101 return EXIT_FAILURE;
102 }
103 }
104 startRmcpReceive();
Tom Joseph7fd26dd2017-03-14 15:26:26 +0530105
Vernon Mauerycbccb052018-10-24 13:52:22 -0700106 io->run();
Tom Joseph7fd26dd2017-03-14 15:26:26 +0530107
Vernon Mauerycbccb052018-10-24 13:52:22 -0700108 return EXIT_SUCCESS;
Tom Joseph7fd26dd2017-03-14 15:26:26 +0530109}
110
Tom Joseph7fd26dd2017-03-14 15:26:26 +0530111} // namespace eventloop