1 /*
2 * SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include "MctpRequester.hpp"
7 #include "Utils.hpp"
8
9 #include <NvidiaDeviceDiscovery.hpp>
10 #include <NvidiaPcieDevice.hpp>
11 #include <NvidiaSmaDevice.hpp>
12 #include <boost/asio/error.hpp>
13 #include <boost/asio/io_context.hpp>
14 #include <boost/asio/post.hpp>
15 #include <boost/asio/steady_timer.hpp>
16 #include <boost/container/flat_map.hpp>
17 #include <phosphor-logging/lg2.hpp>
18 #include <sdbusplus/asio/connection.hpp>
19 #include <sdbusplus/asio/object_server.hpp>
20 #include <sdbusplus/bus.hpp>
21 #include <sdbusplus/bus/match.hpp>
22 #include <sdbusplus/message.hpp>
23
24 #include <array>
25 #include <chrono>
26 #include <cstdlib>
27 #include <exception>
28 #include <functional>
29 #include <memory>
30 #include <string>
31 #include <vector>
32
33 boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>> gpuDevices;
34 boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>> smaDevices;
35 boost::container::flat_map<std::string, std::shared_ptr<PcieDevice>>
36 pcieDevices;
37
configTimerExpiryCallback(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,std::shared_ptr<sdbusplus::asio::connection> & dbusConnection,mctp::MctpRequester & mctpRequester,const boost::system::error_code & ec)38 void configTimerExpiryCallback(
39 boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
40 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
41 mctp::MctpRequester& mctpRequester, const boost::system::error_code& ec)
42 {
43 if (ec == boost::asio::error::operation_aborted)
44 {
45 return; // we're being canceled
46 }
47 createSensors(io, objectServer, gpuDevices, smaDevices, pcieDevices,
48 dbusConnection, mctpRequester);
49 }
50
main()51 int main()
52 {
53 boost::asio::io_context io;
54 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
55 sdbusplus::asio::object_server objectServer(systemBus, true);
56 objectServer.add_manager("/xyz/openbmc_project/sensors");
57 objectServer.add_manager("/xyz/openbmc_project/inventory");
58 objectServer.add_manager("/xyz/openbmc_project/software");
59 objectServer.add_manager("/xyz/openbmc_project/metric");
60 systemBus->request_name("xyz.openbmc_project.GpuSensor");
61
62 mctp::MctpRequester mctpRequester(io);
63
64 boost::asio::post(io, [&]() {
65 createSensors(io, objectServer, gpuDevices, smaDevices, pcieDevices,
66 systemBus, mctpRequester);
67 });
68
69 boost::asio::steady_timer configTimer(io);
70
71 std::function<void(sdbusplus::message_t&)> eventHandler =
72 [&configTimer, &io, &objectServer, &systemBus,
73 &mctpRequester](sdbusplus::message_t&) {
74 configTimer.expires_after(std::chrono::seconds(1));
75 // create a timer because normally multiple properties change
76 configTimer.async_wait(std::bind_front(
77 configTimerExpiryCallback, std::ref(io), std::ref(objectServer),
78 std::ref(systemBus), std::ref(mctpRequester)));
79 };
80
81 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
82 setupPropertiesChangedMatches(
83 *systemBus, std::to_array<const char*>({deviceType}), eventHandler);
84
85 // Watch for entity-manager to remove configuration interfaces
86 // so the corresponding sensors can be removed.
87 auto ifaceRemovedMatch = std::make_shared<sdbusplus::bus::match_t>(
88 static_cast<sdbusplus::bus_t&>(*systemBus),
89 sdbusplus::bus::match::rules::interfacesRemovedAtPath(
90 std::string(inventoryPath)),
91 [](sdbusplus::message_t& msg) {
92 interfaceRemoved(msg, gpuDevices, smaDevices, pcieDevices);
93 });
94
95 try
96 {
97 io.run();
98 }
99 catch (const std::exception& e)
100 {
101 lg2::error("fatal error caught during processing: {MSG}", "MSG",
102 e.what());
103 return EXIT_FAILURE;
104 }
105
106 return 0;
107 }
108