1 #pragma once 2 3 #include "pid/ec/pid.hpp" 4 5 #include <phosphor-logging/log.hpp> 6 #include <sdbusplus/bus.hpp> 7 8 #include <limits> 9 #include <string> 10 11 void tryRestartControlLoops(void); 12 13 /* 14 * Given a configuration structure, fill out the information we use within the 15 * PID loop. 16 */ 17 void initializePIDStruct(ec::pid_info_t* info, const ec::pidinfo& initial); 18 19 void dumpPIDStruct(ec::pid_info_t* info); 20 21 struct SensorProperties 22 { 23 int64_t scale; 24 double value; 25 double min; 26 double max; 27 std::string unit; 28 }; 29 30 struct SensorThresholds 31 { 32 double lowerThreshold = std::numeric_limits<double>::quiet_NaN(); 33 double upperThreshold = std::numeric_limits<double>::quiet_NaN(); 34 }; 35 36 const std::string sensorintf = "xyz.openbmc_project.Sensor.Value"; 37 const std::string criticalThreshInf = 38 "xyz.openbmc_project.Sensor.Threshold.Critical"; 39 const std::string propertiesintf = "org.freedesktop.DBus.Properties"; 40 41 class DbusHelperInterface 42 { 43 public: 44 virtual ~DbusHelperInterface() = default; 45 46 /** @brief Get the service providing the interface for the path. 47 * 48 * @warning Throws exception on dbus failure. 49 */ 50 virtual std::string getService(sdbusplus::bus::bus& bus, 51 const std::string& intf, 52 const std::string& path) = 0; 53 54 /** @brief Get all Sensor.Value properties for a service and path. 55 * 56 * @param[in] bus - A bus to use for the call. 57 * @param[in] service - The service providing the interface. 58 * @param[in] path - The dbus path. 59 * @param[out] prop - A pointer to a properties struct to fill out. 60 * 61 * @warning Throws exception on dbus failure. 62 */ 63 virtual void getProperties(sdbusplus::bus::bus& bus, 64 const std::string& service, 65 const std::string& path, 66 struct SensorProperties* prop) = 0; 67 68 /** @brief Get Critical Threshold current assert status 69 * 70 * @param[in] bus - A bus to use for the call. 71 * @param[in] service - The service providing the interface. 72 * @param[in] path - The dbus path. 73 */ 74 virtual bool thresholdsAsserted(sdbusplus::bus::bus& bus, 75 const std::string& service, 76 const std::string& path) = 0; 77 }; 78 79 class DbusHelper : public DbusHelperInterface 80 { 81 public: 82 DbusHelper() = default; 83 ~DbusHelper() = default; 84 DbusHelper(const DbusHelper&) = default; 85 DbusHelper& operator=(const DbusHelper&) = default; 86 DbusHelper(DbusHelper&&) = default; 87 DbusHelper& operator=(DbusHelper&&) = default; 88 89 std::string getService(sdbusplus::bus::bus& bus, const std::string& intf, 90 const std::string& path) override; 91 92 void getProperties(sdbusplus::bus::bus& bus, const std::string& service, 93 const std::string& path, 94 struct SensorProperties* prop) override; 95 96 bool thresholdsAsserted(sdbusplus::bus::bus& bus, 97 const std::string& service, 98 const std::string& path) override; 99 100 template <typename T> 101 void getProperty(sdbusplus::bus::bus& bus, const std::string& service, 102 const std::string& path, const std::string& interface, 103 const std::string& propertyName, T& prop) 104 { 105 namespace log = phosphor::logging; 106 107 auto msg = bus.new_method_call(service.c_str(), path.c_str(), 108 propertiesintf.c_str(), "Get"); 109 110 msg.append(interface, propertyName); 111 112 std::variant<T> result; 113 try 114 { 115 auto valueResponseMsg = bus.call(msg); 116 valueResponseMsg.read(result); 117 } 118 catch (const sdbusplus::exception::SdBusError& ex) 119 { 120 log::log<log::level::ERR>("Get Property Failed", 121 log::entry("WHAT=%s", ex.what())); 122 throw; 123 } 124 125 prop = std::get<T>(result); 126 } 127 }; 128 129 std::string getSensorPath(const std::string& type, const std::string& id); 130 std::string getMatch(const std::string& type, const std::string& id); 131 void scaleSensorReading(const double min, const double max, double& value); 132 bool validType(const std::string& type); 133 134 struct VariantToDoubleVisitor 135 { 136 template <typename T> 137 std::enable_if_t<std::is_arithmetic<T>::value, double> 138 operator()(const T& t) const 139 { 140 return static_cast<double>(t); 141 } 142 143 template <typename T> 144 std::enable_if_t<!std::is_arithmetic<T>::value, double> 145 operator()(const T& t) const 146 { 147 throw std::invalid_argument("Cannot translate type to double"); 148 } 149 }; 150 151 /* 152 * Given a path that optionally has a glob portion, fill it out. 153 */ 154 std::string FixupPath(std::string original); 155