diff options
author | Tom Joseph <tomjoseph@in.ibm.com> | 2017-03-14 15:26:26 +0530 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2017-04-24 16:11:14 +0000 |
commit | 7fd26ddbf61f0ba4958e9ee61f342a8859deb79b (patch) | |
tree | 1f4462e411ab851b43dd44764fa38f4b65246d09 /sd_event_loop.cpp | |
parent | 52f53d7d84e96264c0d6bc3b5c328f22b37a3d24 (diff) | |
download | phosphor-net-ipmid-7fd26ddbf61f0ba4958e9ee61f342a8859deb79b.tar.gz phosphor-net-ipmid-7fd26ddbf61f0ba4958e9ee61f342a8859deb79b.zip |
Implement startEventLoop and handler function for IPMI packets
The startEventLoop would start the sd_event_loop and register
the handler for IPMI incoming packets on UDP standard port 623.
Change-Id: Ia8ff44961686c1bf715413ff58bd60d7c71f1be1
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
Diffstat (limited to 'sd_event_loop.cpp')
-rw-r--r-- | sd_event_loop.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/sd_event_loop.cpp b/sd_event_loop.cpp new file mode 100644 index 0000000..a99cf56 --- /dev/null +++ b/sd_event_loop.cpp @@ -0,0 +1,133 @@ +#include <sys/ioctl.h> +#include <systemd/sd-daemon.h> +#include <phosphor-logging/log.hpp> +#include "main.hpp" +#include "message_handler.hpp" +#include "sd_event_loop.hpp" + +namespace eventloop +{ +using namespace phosphor::logging; + +static int udp623Handler(sd_event_source* es, int fd, uint32_t revents, + void* userdata) +{ + std::shared_ptr<udpsocket::Channel> channelPtr; + struct timeval timeout; + timeout.tv_sec = SELECT_CALL_TIMEOUT; + timeout.tv_usec = 0; + + try + { + channelPtr.reset(new udpsocket::Channel(fd, timeout)); + + // Initialize the Message Handler with the socket channel + message::Handler msgHandler(channelPtr); + + + std::unique_ptr<message::Message> inMessage; + + // Read the incoming IPMI packet + inMessage = msgHandler.receive(); + if (inMessage == nullptr) + { + return 0; + } + + // Execute the Command + auto outMessage = msgHandler.executeCommand(*(inMessage.get())); + if (outMessage == nullptr) + { + return 0; + } + + // Send the response IPMI Message + msgHandler.send(*(outMessage.get())); + } + catch (std::exception& e) + { + log<level::ERR>("Executing the IPMI message failed"); + log<level::ERR>(e.what()); + } + + return 0; +} + +int EventLoop::startEventLoop() +{ + int fd = -1; + int r = 0; + sigset_t ss; + sd_event_source* source = nullptr; + + r = sd_event_default(&event); + if (r < 0) + { + goto finish; + } + + if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 || + sigaddset(&ss, SIGINT) < 0) + { + r = -errno; + goto finish; + } + + /* Block SIGTERM first, so that the event loop can handle it */ + if (sigprocmask(SIG_BLOCK, &ss, nullptr) < 0) + { + r = -errno; + goto finish; + } + + /* Let's make use of the default handler and "floating" reference features + * of sd_event_add_signal() */ + r = sd_event_add_signal(event, nullptr, SIGTERM, nullptr, nullptr); + if (r < 0) + { + goto finish; + } + + r = sd_event_add_signal(event, nullptr, SIGINT, nullptr, nullptr); + if (r < 0) + { + goto finish; + } + + if (sd_listen_fds(0) != 1) + { + log<level::ERR>("No or too many file descriptors received"); + goto finish; + } + + fd = SD_LISTEN_FDS_START; + + r = sd_event_add_io(event, &source, fd, EPOLLIN, udp623Handler, nullptr); + if (r < 0) + { + goto finish; + } + + udpIPMI.reset(source); + source = nullptr; + + r = sd_event_loop(event); + +finish: + event = sd_event_unref(event); + + if (fd >= 0) + { + (void) close(fd); + } + + if (r < 0) + { + log<level::ERR>("Event Loop Failure:", + entry("FAILURE=%s", strerror(-r))); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} + +} // namespace eventloop |