blob: 7930dba5a03c3040a234647a57185d4c823aad6e [file] [log] [blame]
Patrick Venturee6206562018-03-08 15:36:53 -08001#pragma once
2
James Feist0c8223b2019-05-08 15:33:33 -07003#include "pid/ec/pid.hpp"
4
James Feist5ec20272019-07-10 11:59:57 -07005#include <phosphor-logging/log.hpp>
James Feist0c8223b2019-05-08 15:33:33 -07006#include <sdbusplus/bus.hpp>
Patrick Venturea83a3ec2020-08-04 09:52:05 -07007
8#include <limits>
Patrick Ventureda064282018-06-12 19:33:47 -07009#include <string>
10
Yong Li298a95c2020-04-07 15:11:02 +080011void tryRestartControlLoops(void);
James Feist1fe08952019-05-07 09:17:16 -070012
James Feist0c8223b2019-05-08 15:33:33 -070013/*
14 * Given a configuration structure, fill out the information we use within the
15 * PID loop.
16 */
17void initializePIDStruct(ec::pid_info_t* info, const ec::pidinfo& initial);
18
19void dumpPIDStruct(ec::pid_info_t* info);
20
21struct SensorProperties
22{
23 int64_t scale;
24 double value;
25 double min;
26 double max;
27 std::string unit;
28};
29
30struct SensorThresholds
31{
32 double lowerThreshold = std::numeric_limits<double>::quiet_NaN();
33 double upperThreshold = std::numeric_limits<double>::quiet_NaN();
34};
35
36const std::string sensorintf = "xyz.openbmc_project.Sensor.Value";
37const std::string criticalThreshInf =
38 "xyz.openbmc_project.Sensor.Threshold.Critical";
39const std::string propertiesintf = "org.freedesktop.DBus.Properties";
40
41class 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
79class 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;
James Feist5ec20272019-07-10 11:59:57 -070099
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 }
James Feist0c8223b2019-05-08 15:33:33 -0700127};
128
129std::string getSensorPath(const std::string& type, const std::string& id);
130std::string getMatch(const std::string& type, const std::string& id);
131void scaleSensorReading(const double min, const double max, double& value);
132bool validType(const std::string& type);
133
134struct 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 */
154std::string FixupPath(std::string original);