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