|  | /* | 
|  | * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & | 
|  | * AFFILIATES. All rights reserved. | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #include "MctpRequester.hpp" | 
|  | #include "Utils.hpp" | 
|  |  | 
|  | #include <NvidiaDeviceDiscovery.hpp> | 
|  | #include <NvidiaSmaDevice.hpp> | 
|  | #include <boost/asio/error.hpp> | 
|  | #include <boost/asio/io_context.hpp> | 
|  | #include <boost/asio/post.hpp> | 
|  | #include <boost/asio/steady_timer.hpp> | 
|  | #include <boost/container/flat_map.hpp> | 
|  | #include <phosphor-logging/lg2.hpp> | 
|  | #include <sdbusplus/asio/connection.hpp> | 
|  | #include <sdbusplus/asio/object_server.hpp> | 
|  | #include <sdbusplus/bus.hpp> | 
|  | #include <sdbusplus/bus/match.hpp> | 
|  | #include <sdbusplus/message.hpp> | 
|  |  | 
|  | #include <array> | 
|  | #include <chrono> | 
|  | #include <cstdlib> | 
|  | #include <exception> | 
|  | #include <functional> | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>> gpuDevices; | 
|  | boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>> smaDevices; | 
|  |  | 
|  | void 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) | 
|  | { | 
|  | if (ec == boost::asio::error::operation_aborted) | 
|  | { | 
|  | return; // we're being canceled | 
|  | } | 
|  | createSensors(io, objectServer, gpuDevices, smaDevices, dbusConnection, | 
|  | mctpRequester); | 
|  | } | 
|  |  | 
|  | int main() | 
|  | { | 
|  | boost::asio::io_context io; | 
|  | auto systemBus = std::make_shared<sdbusplus::asio::connection>(io); | 
|  | sdbusplus::asio::object_server objectServer(systemBus, true); | 
|  | objectServer.add_manager("/xyz/openbmc_project/sensors"); | 
|  | objectServer.add_manager("/xyz/openbmc_project/inventory"); | 
|  | systemBus->request_name("xyz.openbmc_project.GpuSensor"); | 
|  |  | 
|  | mctp::MctpRequester mctpRequester(io); | 
|  |  | 
|  | boost::asio::post(io, [&]() { | 
|  | createSensors(io, objectServer, gpuDevices, smaDevices, systemBus, | 
|  | mctpRequester); | 
|  | }); | 
|  |  | 
|  | boost::asio::steady_timer configTimer(io); | 
|  |  | 
|  | std::function<void(sdbusplus::message_t&)> eventHandler = | 
|  | [&configTimer, &io, &objectServer, &systemBus, | 
|  | &mctpRequester](sdbusplus::message_t&) { | 
|  | configTimer.expires_after(std::chrono::seconds(1)); | 
|  | // create a timer because normally multiple properties change | 
|  | configTimer.async_wait(std::bind_front( | 
|  | configTimerExpiryCallback, std::ref(io), std::ref(objectServer), | 
|  | std::ref(systemBus), std::ref(mctpRequester))); | 
|  | }; | 
|  |  | 
|  | std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches = | 
|  | setupPropertiesChangedMatches( | 
|  | *systemBus, std::to_array<const char*>({deviceType}), eventHandler); | 
|  |  | 
|  | // Watch for entity-manager to remove configuration interfaces | 
|  | // so the corresponding sensors can be removed. | 
|  | auto ifaceRemovedMatch = std::make_shared<sdbusplus::bus::match_t>( | 
|  | static_cast<sdbusplus::bus_t&>(*systemBus), | 
|  | sdbusplus::bus::match::rules::interfacesRemovedAtPath( | 
|  | std::string(inventoryPath)), | 
|  | [](sdbusplus::message_t& msg) { | 
|  | interfaceRemoved(msg, gpuDevices, smaDevices); | 
|  | }); | 
|  |  | 
|  | try | 
|  | { | 
|  | io.run(); | 
|  | } | 
|  | catch (const std::exception& e) | 
|  | { | 
|  | lg2::error("fatal error caught during processing: {MSG}", "MSG", | 
|  | e.what()); | 
|  | return EXIT_FAILURE; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } |