xref: /openbmc/phosphor-net-ipmid/main.cpp (revision ecc8efad10bc2101a434a0c1fbd253eeaa1a3a99)
1 #include "main.hpp"
2 
3 #include "comm_module.hpp"
4 #include "command/guid.hpp"
5 #include "command_table.hpp"
6 #include "message.hpp"
7 #include "message_handler.hpp"
8 #include "socket_channel.hpp"
9 #include "sol_module.hpp"
10 
11 #include <assert.h>
12 #include <dirent.h>
13 #include <dlfcn.h>
14 #include <ipmid/api.h>
15 #include <systemd/sd-daemon.h>
16 #include <systemd/sd-event.h>
17 #include <unistd.h>
18 
19 #include <CLI/CLI.hpp>
20 #include <phosphor-logging/log.hpp>
21 #include <sdbusplus/asio/connection.hpp>
22 #include <tuple>
23 #include <user_channel/channel_layer.hpp>
24 
25 using namespace phosphor::logging;
26 
27 // Tuple of Global Singletons
28 static auto io = std::make_shared<boost::asio::io_context>();
29 session::Manager manager(io);
30 command::Table table;
31 eventloop::EventLoop loop(io);
32 sol::Manager solManager(io);
33 
34 std::tuple<session::Manager&, command::Table&, eventloop::EventLoop&,
35            sol::Manager&>
36     singletonPool(manager, table, loop, solManager);
37 
38 sd_bus* bus = nullptr;
39 
40 std::shared_ptr<sdbusplus::asio::connection> sdbusp;
41 
42 /*
43  * @brief Required by apphandler IPMI Provider Library
44  */
45 sd_bus* ipmid_get_sd_bus_connection()
46 {
47     return bus;
48 }
49 
50 /*
51  * @brief mechanism to get at sdbusplus object
52  */
53 std::shared_ptr<sdbusplus::asio::connection> getSdBus()
54 {
55     return sdbusp;
56 }
57 
58 static EInterfaceIndex currentInterfaceIndex = interfaceUnknown;
59 static void setInterfaceIndex(const std::string& channel)
60 {
61     try
62     {
63         currentInterfaceIndex =
64             static_cast<EInterfaceIndex>(ipmi::getChannelByName(channel));
65     }
66     catch (const std::exception& e)
67     {
68         log<level::ERR>("Requested channel name is not a valid channel name",
69                         entry("ERROR=%s", e.what()),
70                         entry("CHANNEL=%s", channel.c_str()));
71     }
72 }
73 EInterfaceIndex getInterfaceIndex(void)
74 {
75     return currentInterfaceIndex;
76 }
77 
78 int main(int argc, char* argv[])
79 {
80     CLI::App app("KCS RMCP+ bridge");
81     std::string channel;
82     app.add_option("-c,--channel", channel, "channel name. e.g., eth0");
83     uint16_t port = ipmi::rmcpp::defaultPort;
84     app.add_option("-p,--port", port, "port number");
85     bool verbose = false;
86     app.add_option("-v,--verbose", verbose, "print more verbose output");
87     CLI11_PARSE(app, argc, argv);
88 
89     // Connect to system bus
90     auto rc = sd_bus_default_system(&bus);
91     if (rc < 0)
92     {
93         log<level::ERR>("Failed to connect to system bus",
94                         entry("ERROR=%s", strerror(-rc)));
95         return rc;
96     }
97     sdbusp = std::make_shared<sdbusplus::asio::connection>(*io, bus);
98 
99     ipmi::ipmiChannelInit();
100     if (channel.size())
101     {
102         setInterfaceIndex(channel);
103     }
104 
105     std::get<session::Manager&>(singletonPool).managerInit(channel);
106     // Register callback to update cache for a GUID change and cache the GUID
107     command::registerGUIDChangeCallback();
108     cache::guid = command::getSystemGUID();
109 
110     // Register the phosphor-net-ipmid session setup commands
111     command::sessionSetupCommands();
112 
113     // Register the phosphor-net-ipmid SOL commands
114     sol::command::registerCommands();
115 
116     auto& loop = std::get<eventloop::EventLoop&>(singletonPool);
117     if (loop.setupSocket(sdbusp, channel))
118     {
119         return EXIT_FAILURE;
120     }
121 
122     // Start Event Loop
123     return loop.startEventLoop();
124 }
125