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