blob: a99cf5661132b3db94a7ba740dad41798f2b8d10 [file] [log] [blame]
Tom Joseph7fd26dd2017-03-14 15:26:26 +05301#include <sys/ioctl.h>
2#include <systemd/sd-daemon.h>
3#include <phosphor-logging/log.hpp>
4#include "main.hpp"
5#include "message_handler.hpp"
6#include "sd_event_loop.hpp"
7
8namespace eventloop
9{
10using namespace phosphor::logging;
11
12static int udp623Handler(sd_event_source* es, int fd, uint32_t revents,
13 void* userdata)
14{
15 std::shared_ptr<udpsocket::Channel> channelPtr;
16 struct timeval timeout;
17 timeout.tv_sec = SELECT_CALL_TIMEOUT;
18 timeout.tv_usec = 0;
19
20 try
21 {
22 channelPtr.reset(new udpsocket::Channel(fd, timeout));
23
24 // Initialize the Message Handler with the socket channel
25 message::Handler msgHandler(channelPtr);
26
27
28 std::unique_ptr<message::Message> inMessage;
29
30 // Read the incoming IPMI packet
31 inMessage = msgHandler.receive();
32 if (inMessage == nullptr)
33 {
34 return 0;
35 }
36
37 // Execute the Command
38 auto outMessage = msgHandler.executeCommand(*(inMessage.get()));
39 if (outMessage == nullptr)
40 {
41 return 0;
42 }
43
44 // Send the response IPMI Message
45 msgHandler.send(*(outMessage.get()));
46 }
47 catch (std::exception& e)
48 {
49 log<level::ERR>("Executing the IPMI message failed");
50 log<level::ERR>(e.what());
51 }
52
53 return 0;
54}
55
56int EventLoop::startEventLoop()
57{
58 int fd = -1;
59 int r = 0;
60 sigset_t ss;
61 sd_event_source* source = nullptr;
62
63 r = sd_event_default(&event);
64 if (r < 0)
65 {
66 goto finish;
67 }
68
69 if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 ||
70 sigaddset(&ss, SIGINT) < 0)
71 {
72 r = -errno;
73 goto finish;
74 }
75
76 /* Block SIGTERM first, so that the event loop can handle it */
77 if (sigprocmask(SIG_BLOCK, &ss, nullptr) < 0)
78 {
79 r = -errno;
80 goto finish;
81 }
82
83 /* Let's make use of the default handler and "floating" reference features
84 * of sd_event_add_signal() */
85 r = sd_event_add_signal(event, nullptr, SIGTERM, nullptr, nullptr);
86 if (r < 0)
87 {
88 goto finish;
89 }
90
91 r = sd_event_add_signal(event, nullptr, SIGINT, nullptr, nullptr);
92 if (r < 0)
93 {
94 goto finish;
95 }
96
97 if (sd_listen_fds(0) != 1)
98 {
99 log<level::ERR>("No or too many file descriptors received");
100 goto finish;
101 }
102
103 fd = SD_LISTEN_FDS_START;
104
105 r = sd_event_add_io(event, &source, fd, EPOLLIN, udp623Handler, nullptr);
106 if (r < 0)
107 {
108 goto finish;
109 }
110
111 udpIPMI.reset(source);
112 source = nullptr;
113
114 r = sd_event_loop(event);
115
116finish:
117 event = sd_event_unref(event);
118
119 if (fd >= 0)
120 {
121 (void) close(fd);
122 }
123
124 if (r < 0)
125 {
126 log<level::ERR>("Event Loop Failure:",
127 entry("FAILURE=%s", strerror(-r)));
128 }
129
130 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
131}
132
133} // namespace eventloop