Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <boost/algorithm/string/predicate.hpp>
- #include <boost/asio.hpp>
- #include <phosphor-logging/lg2.hpp>
- #include <sdbusplus/asio/connection.hpp>
- #include <sdbusplus/asio/property.hpp>
- #include <sdbusplus/bus/match.hpp>
- constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; // NOLINT
- constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; // NOLINT
- constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; // NOLINT
- constexpr auto hostBusname = "xyz.openbmc_project.State.Host";
- constexpr auto hostInterface = "xyz.openbmc_project.State.Host";
- constexpr auto hostPath = "/xyz/openbmc_project/state/host0";
- constexpr auto hostProperty = "CurrentHostState";
- PHOSPHOR_LOG2_USING;
- constexpr size_t numOfSensors = 14;
- using SensorValues = std::array<uint8_t, numOfSensors>;
- constexpr auto sensorValueInterface = "xyz.openbmc_project.Sensor.Value";
- constexpr auto propertyValue = "Value";
- constexpr std::array<const char*, numOfSensors> sensorObjects = {
- "/xyz/openbmc_project/sensors/temperature/Inlet0_Temp",
- "/xyz/openbmc_project/sensors/temperature/Inlet1_Temp",
- "/xyz/openbmc_project/sensors/temperature/Outlet0_Temp",
- "/xyz/openbmc_project/sensors/temperature/Outlet1_Temp",
- "/xyz/openbmc_project/sensors/temperature/CPU_Temp",
- "/xyz/openbmc_project/sensors/temperature/DIMM_Temp",
- "/xyz/openbmc_project/sensors/temperature/CPU_VR_Temp",
- "/xyz/openbmc_project/sensors/temperature/Mdot2_Temp",
- "/xyz/openbmc_project/sensors/temperature/DRAM0_Temp",
- "/xyz/openbmc_project/sensors/temperature/DRAM1_Temp",
- "/xyz/openbmc_project/sensors/temperature/DRAM2_Temp",
- "/xyz/openbmc_project/sensors/temperature/FPGA_Temp",
- "/xyz/openbmc_project/sensors/temperature/DSPF_Temp",
- "/xyz/openbmc_project/sensors/temperature/FPGA_VR_Temp",
- };
- std::array<std::optional<std::string>, numOfSensors> sensorServices;
- SensorValues sensorValues;
- std::string getService(sdbusplus::bus::bus& bus, const char* path,
- const char* interface)
- {
- auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
- MAPPER_INTERFACE, "GetObject");
- mapper.append(path, std::vector<std::string>({interface}));
- try
- {
- auto mapperResponseMsg = bus.call(mapper);
- std::vector<std::pair<std::string, std::vector<std::string>>>
- mapperResponse;
- mapperResponseMsg.read(mapperResponse);
- if (mapperResponse.empty())
- {
- throw std::runtime_error("Error reading mapper response");
- }
- std::vector<std::string> ret;
- ret.reserve(mapperResponse.size());
- for (const auto& i : mapperResponse)
- {
- ret.emplace_back(i.first);
- }
- return ret[0];
- }
- catch (const sdbusplus::exception::SdBusError& ex)
- {
- throw std::runtime_error("GetObject call failed");
- }
- }
- using PropertyType = std::variant<std::string, bool, double>;
- template <typename T>
- T getProperty(sdbusplus::bus::bus& bus, const char* service,
- const char* path, const char* interface,
- const char* propertyName)
- {
- auto method = bus.new_method_call(service, path,
- "org.freedesktop.DBus.Properties", "Get");
- method.append(interface, propertyName);
- try
- {
- PropertyType value{};
- auto reply = bus.call(method);
- reply.read(value);
- auto ret = std::get<T>(value);
- return ret;
- }
- catch (const sdbusplus::exception::SdBusError& ex)
- {
- throw std::runtime_error("GetProperty call failed");
- }
- }
- void getSensors(sdbusplus::bus::bus& bus)
- {
- // Read the sensors multiple times to make the issue more reproducible
- for (int j = 0; j < 10; ++j)
- {
- for (size_t i = 0; i < numOfSensors; ++i)
- {
- try
- {
- const auto& sensor = sensorObjects[i];
- auto& service = sensorServices[i];
- if (!service)
- {
- service = getService(bus, sensor, sensorValueInterface);
- }
- auto value =
- getProperty<double>(bus, service->c_str(), sensor,
- sensorValueInterface, propertyValue);
- sensorValues[i] = static_cast<uint32_t>(value);
- }
- catch (const std::runtime_error& ex)
- {
- sensorServices[i].reset();
- sensorValues[i] = 0;
- continue;
- }
- }
- }
- }
- void timerHandler(const boost::system::error_code& ec, sdbusplus::bus::bus& bus,
- boost::asio::steady_timer& t)
- {
- if (ec)
- {
- lg2::error("Error occurs");
- return;
- }
- getSensors(bus);
- t.expires_from_now(std::chrono::seconds(1));
- t.async_wait([&](const boost::system::error_code& ec) {
- timerHandler(ec, std::ref(bus), std::ref(t));
- });
- }
- int main(int /*argc*/, char** /*argv*/)
- {
- boost::asio::io_context io;
- boost::asio::steady_timer t(io, std::chrono::seconds(1));
- auto bus = std::make_shared<sdbusplus::asio::connection>(io);
- t.async_wait([&](const boost::system::error_code& ec) {
- timerHandler(ec, std::ref(static_cast<sdbusplus::bus::bus&>(*bus)),
- std::ref(t));
- });
- // Match for host power monitor
- namespace rules = sdbusplus::bus::match::rules;
- sdbusplus::bus::match::match m(
- static_cast<sdbusplus::bus::bus&>(*bus),
- rules::propertiesChanged(hostPath, hostInterface),
- [](sdbusplus::message::message& message) {
- std::string objectName;
- std::map<std::string, std::variant<std::string>> values;
- message.read(objectName, values);
- for (const auto& it : values)
- {
- auto v = std::get<std::string>(it.second);
- lg2::info("aiso callback, property: {PROP}, value: {VALUE}", "PROP", it.first, "VALUE", v);
- }
- });
- io.run();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement