blob: 93efc6d457ed55c6a2415cb95e87b9f68699eb49 [file] [log] [blame]
James Feist0c8223b2019-05-08 15:33:33 -07001#include "util.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07002
Patrick Venturea83a3ec2020-08-04 09:52:05 -07003#include <phosphor-logging/log.hpp>
4
James Feist36b7d8e2018-10-05 15:39:01 -07005#include <cmath>
Patrick Venture863b9242018-03-08 08:29:23 -08006#include <iostream>
Patrick Venture0ef1faf2018-06-13 12:50:53 -07007#include <set>
James Feist1f802f52019-02-08 13:51:43 -08008#include <variant>
Patrick Venture863b9242018-03-08 08:29:23 -08009
Patrick Venture863b9242018-03-08 08:29:23 -080010using Property = std::string;
James Feist1f802f52019-02-08 13:51:43 -080011using Value = std::variant<int64_t, double, std::string, bool>;
Patrick Venture863b9242018-03-08 08:29:23 -080012using PropertyMap = std::map<Property, Value>;
13
Patrick Venture34ddc902018-10-30 11:05:17 -070014using namespace phosphor::logging;
15
Patrick Venture863b9242018-03-08 08:29:23 -080016/* TODO(venture): Basically all phosphor apps need this, maybe it should be a
17 * part of sdbusplus. There is an old version in libmapper.
18 */
Patrick Venture563a3562018-10-30 09:31:26 -070019std::string DbusHelper::getService(sdbusplus::bus::bus& bus,
Patrick Venture0df7c0f2018-06-13 09:02:13 -070020 const std::string& intf,
21 const std::string& path)
Patrick Venture863b9242018-03-08 08:29:23 -080022{
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070023 auto mapper =
24 bus.new_method_call("xyz.openbmc_project.ObjectMapper",
25 "/xyz/openbmc_project/object_mapper",
26 "xyz.openbmc_project.ObjectMapper", "GetObject");
Patrick Venture863b9242018-03-08 08:29:23 -080027
28 mapper.append(path);
29 mapper.append(std::vector<std::string>({intf}));
30
Patrick Venture863b9242018-03-08 08:29:23 -080031 std::map<std::string, std::vector<std::string>> response;
Patrick Venture34ddc902018-10-30 11:05:17 -070032
33 try
34 {
35 auto responseMsg = bus.call(mapper);
36
37 responseMsg.read(response);
38 }
39 catch (const sdbusplus::exception::SdBusError& ex)
40 {
41 log<level::ERR>("ObjectMapper call failure",
42 entry("WHAT=%s", ex.what()));
43 throw;
44 }
Patrick Venture863b9242018-03-08 08:29:23 -080045
46 if (response.begin() == response.end())
47 {
48 throw std::runtime_error("Unable to find Object: " + path);
49 }
50
51 return response.begin()->first;
52}
53
Patrick Venture563a3562018-10-30 09:31:26 -070054void DbusHelper::getProperties(sdbusplus::bus::bus& bus,
Patrick Venture0df7c0f2018-06-13 09:02:13 -070055 const std::string& service,
56 const std::string& path,
57 struct SensorProperties* prop)
Patrick Venture863b9242018-03-08 08:29:23 -080058{
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070059 auto pimMsg = bus.new_method_call(service.c_str(), path.c_str(),
60 propertiesintf.c_str(), "GetAll");
Patrick Venture863b9242018-03-08 08:29:23 -080061
62 pimMsg.append(sensorintf);
Patrick Venture863b9242018-03-08 08:29:23 -080063
Patrick Venture7dbc5172018-10-30 12:18:45 -070064 PropertyMap propMap;
65
66 try
Patrick Venture863b9242018-03-08 08:29:23 -080067 {
Patrick Venture7dbc5172018-10-30 12:18:45 -070068 auto valueResponseMsg = bus.call(pimMsg);
69 valueResponseMsg.read(propMap);
70 }
71 catch (const sdbusplus::exception::SdBusError& ex)
72 {
73 log<level::ERR>("GetAll Properties Failed",
74 entry("WHAT=%s", ex.what()));
75 throw;
Patrick Venture863b9242018-03-08 08:29:23 -080076 }
77
78 // The PropertyMap returned will look like this because it's always
79 // reading a Sensor.Value interface.
80 // a{sv} 3:
81 // "Value" x 24875
82 // "Unit" s "xyz.openbmc_project.Sensor.Value.Unit.DegreesC"
83 // "Scale" x -3
Patrick Venture863b9242018-03-08 08:29:23 -080084
Patrick Venture0d73b102018-05-09 10:29:42 -070085 // If no error was set, the values should all be there.
James Feistc065cf12018-07-05 10:23:11 -070086 auto findUnit = propMap.find("Unit");
87 if (findUnit != propMap.end())
88 {
James Feist1f802f52019-02-08 13:51:43 -080089 prop->unit = std::get<std::string>(findUnit->second);
James Feistc065cf12018-07-05 10:23:11 -070090 }
91 auto findScale = propMap.find("Scale");
James Feist75eb7692019-02-25 12:50:02 -080092 auto findMax = propMap.find("MaxValue");
93 auto findMin = propMap.find("MinValue");
94
95 prop->min = 0;
96 prop->max = 0;
97 prop->scale = 0;
James Feistc065cf12018-07-05 10:23:11 -070098 if (findScale != propMap.end())
99 {
James Feist1f802f52019-02-08 13:51:43 -0800100 prop->scale = std::get<int64_t>(findScale->second);
James Feistc065cf12018-07-05 10:23:11 -0700101 }
James Feist75eb7692019-02-25 12:50:02 -0800102 if (findMax != propMap.end())
James Feistc065cf12018-07-05 10:23:11 -0700103 {
James Feist75eb7692019-02-25 12:50:02 -0800104 prop->max = std::visit(VariantToDoubleVisitor(), findMax->second);
105 }
106 if (findMin != propMap.end())
107 {
108 prop->min = std::visit(VariantToDoubleVisitor(), findMin->second);
James Feistc065cf12018-07-05 10:23:11 -0700109 }
110
James Feist1f802f52019-02-08 13:51:43 -0800111 prop->value = std::visit(VariantToDoubleVisitor(), propMap["Value"]);
Patrick Venture863b9242018-03-08 08:29:23 -0800112
113 return;
114}
115
Patrick Venture563a3562018-10-30 09:31:26 -0700116bool DbusHelper::thresholdsAsserted(sdbusplus::bus::bus& bus,
James Feist36b7d8e2018-10-05 15:39:01 -0700117 const std::string& service,
118 const std::string& path)
119{
120
121 auto critical = bus.new_method_call(service.c_str(), path.c_str(),
122 propertiesintf.c_str(), "GetAll");
123 critical.append(criticalThreshInf);
124 PropertyMap criticalMap;
125
126 try
127 {
128 auto msg = bus.call(critical);
Patrick Venture4fd8cff2018-10-31 14:24:12 -0700129 msg.read(criticalMap);
James Feist36b7d8e2018-10-05 15:39:01 -0700130 }
131 catch (sdbusplus::exception_t&)
132 {
133 // do nothing, sensors don't have to expose critical thresholds
134 return false;
135 }
136
137 auto findCriticalLow = criticalMap.find("CriticalAlarmLow");
138 auto findCriticalHigh = criticalMap.find("CriticalAlarmHigh");
139
140 bool asserted = false;
141 if (findCriticalLow != criticalMap.end())
142 {
James Feist1f802f52019-02-08 13:51:43 -0800143 asserted = std::get<bool>(findCriticalLow->second);
James Feist36b7d8e2018-10-05 15:39:01 -0700144 }
145
146 // as we are catching properties changed, a sensor could theoretically jump
147 // from one threshold to the other in one event, so check both thresholds
148 if (!asserted && findCriticalHigh != criticalMap.end())
149 {
James Feist1f802f52019-02-08 13:51:43 -0800150 asserted = std::get<bool>(findCriticalHigh->second);
James Feist36b7d8e2018-10-05 15:39:01 -0700151 }
152 return asserted;
153}
154
Patrick Venture7af157b2018-10-30 11:24:40 -0700155std::string getSensorPath(const std::string& type, const std::string& id)
Patrick Venture863b9242018-03-08 08:29:23 -0800156{
157 std::string layer = type;
158 if (type == "fan")
159 {
160 layer = "fan_tach";
161 }
162 else if (type == "temp")
163 {
164 layer = "temperature";
165 }
166 else
167 {
168 layer = "unknown"; // TODO(venture): Need to handle.
169 }
170
171 return std::string("/xyz/openbmc_project/sensors/" + layer + "/" + id);
172}
173
Patrick Venture7af157b2018-10-30 11:24:40 -0700174std::string getMatch(const std::string& type, const std::string& id)
Patrick Venture863b9242018-03-08 08:29:23 -0800175{
176 return std::string("type='signal',"
177 "interface='org.freedesktop.DBus.Properties',"
178 "member='PropertiesChanged',"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700179 "path='" +
Patrick Venture7af157b2018-10-30 11:24:40 -0700180 getSensorPath(type, id) + "'");
Patrick Venture863b9242018-03-08 08:29:23 -0800181}
182
Patrick Venture7af157b2018-10-30 11:24:40 -0700183bool validType(const std::string& type)
Patrick Venture0ef1faf2018-06-13 12:50:53 -0700184{
185 static std::set<std::string> valid = {"fan", "temp"};
186 return (valid.find(type) != valid.end());
187}
James Feist75eb7692019-02-25 12:50:02 -0800188
189void scaleSensorReading(const double min, const double max, double& value)
190{
Kun Yi6aae76f2019-07-10 21:58:32 -0700191 if (max <= 0 || max <= min)
James Feist75eb7692019-02-25 12:50:02 -0800192 {
193 return;
194 }
195 value /= (max - min);
James Feist0c8223b2019-05-08 15:33:33 -0700196}