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