103e6defcSWilliam A. Kennington III #include "args.hpp"
203e6defcSWilliam A. Kennington III #include "cmd.hpp"
303e6defcSWilliam A. Kennington III #include "server.hpp"
403e6defcSWilliam A. Kennington III
503e6defcSWilliam A. Kennington III #include <systemd/sd-daemon.h>
603e6defcSWilliam A. Kennington III
703e6defcSWilliam A. Kennington III #include <sdbusplus/bus.hpp>
803e6defcSWilliam A. Kennington III #include <sdbusplus/slot.hpp>
903e6defcSWilliam A. Kennington III #include <sdeventplus/event.hpp>
1003e6defcSWilliam A. Kennington III #include <sdeventplus/source/io.hpp>
1103e6defcSWilliam A. Kennington III #include <sdeventplus/source/signal.hpp>
1203e6defcSWilliam A. Kennington III #include <stdplus/exception.hpp>
1303e6defcSWilliam A. Kennington III #include <stdplus/fd/create.hpp>
14*c0c95be1SPatrick Williams #include <stdplus/print.hpp>
1503e6defcSWilliam A. Kennington III #include <stdplus/signal.hpp>
1603e6defcSWilliam A. Kennington III
1703e6defcSWilliam A. Kennington III #include <algorithm>
18e0602aafSPatrick Williams #include <cstdio>
19e0602aafSPatrick Williams #include <format>
2003e6defcSWilliam A. Kennington III #include <stdexcept>
2103e6defcSWilliam A. Kennington III #include <string>
2203e6defcSWilliam A. Kennington III
2303e6defcSWilliam A. Kennington III namespace kcsbridge
2403e6defcSWilliam A. Kennington III {
2503e6defcSWilliam A. Kennington III
2603e6defcSWilliam A. Kennington III using sdeventplus::source::IO;
2703e6defcSWilliam A. Kennington III using sdeventplus::source::Signal;
2803e6defcSWilliam A. Kennington III using stdplus::fd::OpenAccess;
2903e6defcSWilliam A. Kennington III using stdplus::fd::OpenFlag;
3003e6defcSWilliam A. Kennington III using stdplus::fd::OpenFlags;
3103e6defcSWilliam A. Kennington III
execute(const char * channel)3203e6defcSWilliam A. Kennington III int execute(const char* channel)
3303e6defcSWilliam A. Kennington III {
3403e6defcSWilliam A. Kennington III // Set up our DBus and event loop
3503e6defcSWilliam A. Kennington III auto event = sdeventplus::Event::get_default();
3603e6defcSWilliam A. Kennington III auto bus = sdbusplus::bus::new_default();
3703e6defcSWilliam A. Kennington III bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
3803e6defcSWilliam A. Kennington III
3903e6defcSWilliam A. Kennington III // Configure basic signal handling
4003e6defcSWilliam A. Kennington III auto exit_handler = [&event](Signal&, const struct signalfd_siginfo*) {
41*c0c95be1SPatrick Williams stdplus::print(stderr, "Interrupted, Exiting\n");
4203e6defcSWilliam A. Kennington III event.exit(0);
4303e6defcSWilliam A. Kennington III };
4403e6defcSWilliam A. Kennington III stdplus::signal::block(SIGINT);
4503e6defcSWilliam A. Kennington III Signal sig_int(event, SIGINT, exit_handler);
4603e6defcSWilliam A. Kennington III stdplus::signal::block(SIGTERM);
4703e6defcSWilliam A. Kennington III Signal sig_term(event, SIGTERM, exit_handler);
4803e6defcSWilliam A. Kennington III
4903e6defcSWilliam A. Kennington III // Open an FD for the KCS channel
5003e6defcSWilliam A. Kennington III stdplus::ManagedFd kcs = stdplus::fd::open(
51e0602aafSPatrick Williams std::format("/dev/{}", channel),
5203e6defcSWilliam A. Kennington III OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::NonBlock));
530efeb17fSPatrick Williams sdbusplus::slot_t slot(nullptr);
5403e6defcSWilliam A. Kennington III
5503e6defcSWilliam A. Kennington III // Add a reader to the bus for handling inbound IPMI
5603e6defcSWilliam A. Kennington III IO ioSource(
5703e6defcSWilliam A. Kennington III event, kcs.get(), EPOLLIN | EPOLLET,
584bf990acSPatrick Williams stdplus::exception::ignore([&kcs, &bus, &slot](IO&, int, uint32_t) {
594bf990acSPatrick Williams read(kcs, bus, slot);
604bf990acSPatrick Williams }));
6103e6defcSWilliam A. Kennington III
6203e6defcSWilliam A. Kennington III // Allow processes to affect the state machine
6303e6defcSWilliam A. Kennington III std::string dbusChannel = channel;
6403e6defcSWilliam A. Kennington III std::replace(dbusChannel.begin(), dbusChannel.end(), '-', '_');
6503e6defcSWilliam A. Kennington III auto obj = "/xyz/openbmc_project/Ipmi/Channel/" + dbusChannel;
6603e6defcSWilliam A. Kennington III auto srv = "xyz.openbmc_project.Ipmi.Channel." + dbusChannel;
6703e6defcSWilliam A. Kennington III auto intf = createSMSHandler(bus, obj.c_str(), kcs);
6803e6defcSWilliam A. Kennington III bus.request_name(srv.c_str());
6903e6defcSWilliam A. Kennington III
7003e6defcSWilliam A. Kennington III sd_notify(0, "READY=1");
7103e6defcSWilliam A. Kennington III return event.loop();
7203e6defcSWilliam A. Kennington III }
7303e6defcSWilliam A. Kennington III
7403e6defcSWilliam A. Kennington III } // namespace kcsbridge
7503e6defcSWilliam A. Kennington III
main(int argc,char * argv[])7603e6defcSWilliam A. Kennington III int main(int argc, char* argv[])
7703e6defcSWilliam A. Kennington III {
7803e6defcSWilliam A. Kennington III try
7903e6defcSWilliam A. Kennington III {
8003e6defcSWilliam A. Kennington III kcsbridge::Args args(argc, argv);
8103e6defcSWilliam A. Kennington III return kcsbridge::execute(args.channel);
8203e6defcSWilliam A. Kennington III }
8303e6defcSWilliam A. Kennington III catch (const std::exception& e)
8403e6defcSWilliam A. Kennington III {
85*c0c95be1SPatrick Williams stdplus::print(stderr, "FAILED: {}\n", e.what());
8603e6defcSWilliam A. Kennington III return 1;
8703e6defcSWilliam A. Kennington III }
8803e6defcSWilliam A. Kennington III }
89