xref: /openbmc/kcsbridge/src/main.cpp (revision c0c95be197cc6f863b0c11ca7726f8e34b74f370)
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