blob: b022dc6eba0338609639574ab7ffa24c75405f7a [file] [log] [blame]
John Chunge2fae4b2024-11-13 18:10:31 -06001#include "serialcmd.hpp"
2
3#include <systemd/sd-daemon.h>
4
5#include <CLI/CLI.hpp>
6#include <phosphor-logging/lg2.hpp>
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/fd/ops.hpp>
15#include <stdplus/signal.hpp>
16
17namespace serialbridge
18{
19
20using sdeventplus::source::IO;
21using sdeventplus::source::Signal;
22using stdplus::fd::OpenAccess;
23using stdplus::fd::OpenFlag;
24using stdplus::fd::OpenFlags;
25
26int execute(const std::string& channel, const bool& verbose)
27{
28 // Set up DBus and event loop
29 auto event = sdeventplus::Event::get_default();
30 auto bus = sdbusplus::bus::new_default();
31 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
32
33 // Configure basic signal handling
34 auto exit_handler = [&event](Signal&, const struct signalfd_siginfo*) {
35 lg2::error("Interrupted, Exiting\n");
36 event.exit(0);
37 };
38 stdplus::signal::block(SIGINT);
39 Signal sig_init(event, SIGINT, exit_handler);
40 stdplus::signal::block(SIGTERM);
41 Signal sig_term(event, SIGTERM, exit_handler);
42
43 // Open an FD for the UART channel
44 stdplus::ManagedFd uart = stdplus::fd::open(
45 std::format("/dev/{}", channel.c_str()),
46 OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::NonBlock));
47 sdbusplus::slot_t slot(nullptr);
48
49 std::unique_ptr<SerialChannel> serialchannel =
50 std::make_unique<SerialChannel>(verbose);
51
52 // Add a reader to the bus for handling inbound IPMI
53 IO ioSource(event, uart.get(), EPOLLIN | EPOLLET,
54 stdplus::exception::ignore(
55 [&serialchannel, &uart, &bus, &slot](IO&, int, uint32_t) {
56 serialchannel->read(uart, bus, slot);
57 }));
58
59 sd_notify(0, "READY=1");
60 return event.loop();
61}
62
63} // namespace serialbridge
64
65int main(int argc, char* argv[])
66{
67 std::string device;
68 bool verbose = 0;
69
70 // Parse input parameter
71 CLI::App app("Serial IPMI Bridge");
72 app.add_option("-d,--device", device, "select uart device");
73 app.add_option("-v,--verbose", verbose, "enable debug message");
74 CLI11_PARSE(app, argc, argv);
75
76 try
77 {
78 return serialbridge::execute(device, verbose);
79 }
80 catch (const std::exception& e)
81 {
82 lg2::error("FAILED: {MSG}\n", "MSG", e);
83 return 1;
84 }
85}