blob: e8863e8f9e98202a970a44823708f9af9d8fcc1c [file] [log] [blame]
William A. Kennington III03e6def2021-05-11 15:23:15 -07001#include "args.hpp"
2#include "cmd.hpp"
3#include "server.hpp"
4
5#include <fmt/format.h>
6#include <systemd/sd-daemon.h>
7
8#include <sdbusplus/bus.hpp>
9#include <sdbusplus/slot.hpp>
10#include <sdeventplus/event.hpp>
11#include <sdeventplus/source/io.hpp>
12#include <sdeventplus/source/signal.hpp>
13#include <stdplus/exception.hpp>
14#include <stdplus/fd/create.hpp>
15#include <stdplus/signal.hpp>
16
17#include <algorithm>
18#include <stdexcept>
19#include <string>
20
21namespace kcsbridge
22{
23
24using sdeventplus::source::IO;
25using sdeventplus::source::Signal;
26using stdplus::fd::OpenAccess;
27using stdplus::fd::OpenFlag;
28using stdplus::fd::OpenFlags;
29
30int execute(const char* channel)
31{
32 // Set up our DBus and event loop
33 auto event = sdeventplus::Event::get_default();
34 auto bus = sdbusplus::bus::new_default();
35 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
36
37 // Configure basic signal handling
38 auto exit_handler = [&event](Signal&, const struct signalfd_siginfo*) {
39 fmt::print(stderr, "Interrupted, Exiting\n");
40 event.exit(0);
41 };
42 stdplus::signal::block(SIGINT);
43 Signal sig_int(event, SIGINT, exit_handler);
44 stdplus::signal::block(SIGTERM);
45 Signal sig_term(event, SIGTERM, exit_handler);
46
47 // Open an FD for the KCS channel
48 stdplus::ManagedFd kcs = stdplus::fd::open(
49 fmt::format("/dev/{}", channel),
50 OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::NonBlock));
51 sdbusplus::slot::slot slot(nullptr);
52
53 // Add a reader to the bus for handling inbound IPMI
54 IO ioSource(
55 event, kcs.get(), EPOLLIN | EPOLLET,
56 stdplus::exception::ignore(
57 [&kcs, &bus, &slot](IO&, int, uint32_t) { read(kcs, bus, slot); }));
58
59 // Allow processes to affect the state machine
60 std::string dbusChannel = channel;
61 std::replace(dbusChannel.begin(), dbusChannel.end(), '-', '_');
62 auto obj = "/xyz/openbmc_project/Ipmi/Channel/" + dbusChannel;
63 auto srv = "xyz.openbmc_project.Ipmi.Channel." + dbusChannel;
64 auto intf = createSMSHandler(bus, obj.c_str(), kcs);
65 bus.request_name(srv.c_str());
66
67 sd_notify(0, "READY=1");
68 return event.loop();
69}
70
71} // namespace kcsbridge
72
73int main(int argc, char* argv[])
74{
75 try
76 {
77 kcsbridge::Args args(argc, argv);
78 return kcsbridge::execute(args.channel);
79 }
80 catch (const std::exception& e)
81 {
82 fmt::print(stderr, "FAILED: {}\n", e.what());
83 return 1;
84 }
85}