blob: 6032de04b33965e7066667b528a0dac59e5a485f [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
William A. Kennington III03e6def2021-05-11 15:23:15 -07005#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>
Patrick Williamsc0c95be2024-08-19 16:02:44 -040014#include <stdplus/print.hpp>
William A. Kennington III03e6def2021-05-11 15:23:15 -070015#include <stdplus/signal.hpp>
16
17#include <algorithm>
Patrick Williamse0602aa2023-07-17 11:20:00 -050018#include <cstdio>
19#include <format>
William A. Kennington III03e6def2021-05-11 15:23:15 -070020#include <stdexcept>
21#include <string>
22
23namespace kcsbridge
24{
25
26using sdeventplus::source::IO;
27using sdeventplus::source::Signal;
28using stdplus::fd::OpenAccess;
29using stdplus::fd::OpenFlag;
30using stdplus::fd::OpenFlags;
31
32int 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*) {
Patrick Williamsc0c95be2024-08-19 16:02:44 -040041 stdplus::print(stderr, "Interrupted, Exiting\n");
William A. Kennington III03e6def2021-05-11 15:23:15 -070042 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(
Patrick Williamse0602aa2023-07-17 11:20:00 -050051 std::format("/dev/{}", channel),
William A. Kennington III03e6def2021-05-11 15:23:15 -070052 OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::NonBlock));
Patrick Williams0efeb172022-07-22 19:26:56 -050053 sdbusplus::slot_t slot(nullptr);
William A. Kennington III03e6def2021-05-11 15:23:15 -070054
55 // Add a reader to the bus for handling inbound IPMI
56 IO ioSource(
57 event, kcs.get(), EPOLLIN | EPOLLET,
Patrick Williams4bf990a2024-08-16 15:21:15 -040058 stdplus::exception::ignore([&kcs, &bus, &slot](IO&, int, uint32_t) {
59 read(kcs, bus, slot);
60 }));
William A. Kennington III03e6def2021-05-11 15:23:15 -070061
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
76int 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 {
Patrick Williamsc0c95be2024-08-19 16:02:44 -040085 stdplus::print(stderr, "FAILED: {}\n", e.what());
William A. Kennington III03e6def2021-05-11 15:23:15 -070086 return 1;
87 }
88}