blob: f7dbe41c2863d513a2c5c9c77857fff30d959b6f [file] [log] [blame]
Patrick Ventureaadb30d2020-08-10 09:17:11 -07001/**
2 * Copyright 2017 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "dbushelper.hpp"
18
19#include "dbushelper_interface.hpp"
20#include "dbusutil.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070021
Patrick Venturea83a3ec2020-08-04 09:52:05 -070022#include <phosphor-logging/log.hpp>
Patrick Ventureaadb30d2020-08-10 09:17:11 -070023#include <sdbusplus/bus.hpp>
Patrick Venturea83a3ec2020-08-04 09:52:05 -070024
Patrick Ventureaadb30d2020-08-10 09:17:11 -070025#include <map>
26#include <string>
James Feist1f802f52019-02-08 13:51:43 -080027#include <variant>
Patrick Ventureaadb30d2020-08-10 09:17:11 -070028#include <vector>
29
30namespace pid_control
31{
Patrick Venture863b9242018-03-08 08:29:23 -080032
Patrick Venture863b9242018-03-08 08:29:23 -080033using Property = std::string;
James Feist1f802f52019-02-08 13:51:43 -080034using Value = std::variant<int64_t, double, std::string, bool>;
Patrick Venture863b9242018-03-08 08:29:23 -080035using PropertyMap = std::map<Property, Value>;
36
Patrick Venture34ddc902018-10-30 11:05:17 -070037using namespace phosphor::logging;
38
Patrick Venture863b9242018-03-08 08:29:23 -080039/* TODO(venture): Basically all phosphor apps need this, maybe it should be a
40 * part of sdbusplus. There is an old version in libmapper.
41 */
Patrick Venture9b936922020-08-10 11:28:39 -070042std::string DbusHelper::getService(const std::string& intf,
Patrick Venture0df7c0f2018-06-13 09:02:13 -070043 const std::string& path)
Patrick Venture863b9242018-03-08 08:29:23 -080044{
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070045 auto mapper =
Patrick Venture8729eb92020-08-10 10:38:44 -070046 _bus.new_method_call("xyz.openbmc_project.ObjectMapper",
47 "/xyz/openbmc_project/object_mapper",
48 "xyz.openbmc_project.ObjectMapper", "GetObject");
Patrick Venture863b9242018-03-08 08:29:23 -080049
50 mapper.append(path);
51 mapper.append(std::vector<std::string>({intf}));
52
Patrick Venture863b9242018-03-08 08:29:23 -080053 std::map<std::string, std::vector<std::string>> response;
Patrick Venture34ddc902018-10-30 11:05:17 -070054
55 try
56 {
Patrick Venture8729eb92020-08-10 10:38:44 -070057 auto responseMsg = _bus.call(mapper);
Patrick Venture34ddc902018-10-30 11:05:17 -070058
59 responseMsg.read(response);
60 }
61 catch (const sdbusplus::exception::SdBusError& ex)
62 {
63 log<level::ERR>("ObjectMapper call failure",
64 entry("WHAT=%s", ex.what()));
65 throw;
66 }
Patrick Venture863b9242018-03-08 08:29:23 -080067
68 if (response.begin() == response.end())
69 {
70 throw std::runtime_error("Unable to find Object: " + path);
71 }
72
73 return response.begin()->first;
74}
75
Patrick Venture9b936922020-08-10 11:28:39 -070076void DbusHelper::getProperties(const std::string& service,
Patrick Venture0df7c0f2018-06-13 09:02:13 -070077 const std::string& path,
78 struct SensorProperties* prop)
Patrick Venture863b9242018-03-08 08:29:23 -080079{
Patrick Venture8729eb92020-08-10 10:38:44 -070080 auto pimMsg = _bus.new_method_call(service.c_str(), path.c_str(),
81 propertiesintf, "GetAll");
Patrick Venture863b9242018-03-08 08:29:23 -080082
83 pimMsg.append(sensorintf);
Patrick Venture863b9242018-03-08 08:29:23 -080084
Patrick Venture7dbc5172018-10-30 12:18:45 -070085 PropertyMap propMap;
86
87 try
Patrick Venture863b9242018-03-08 08:29:23 -080088 {
Patrick Venture8729eb92020-08-10 10:38:44 -070089 auto valueResponseMsg = _bus.call(pimMsg);
Patrick Venture7dbc5172018-10-30 12:18:45 -070090 valueResponseMsg.read(propMap);
91 }
92 catch (const sdbusplus::exception::SdBusError& ex)
93 {
94 log<level::ERR>("GetAll Properties Failed",
95 entry("WHAT=%s", ex.what()));
96 throw;
Patrick Venture863b9242018-03-08 08:29:23 -080097 }
98
99 // The PropertyMap returned will look like this because it's always
100 // reading a Sensor.Value interface.
101 // a{sv} 3:
102 // "Value" x 24875
103 // "Unit" s "xyz.openbmc_project.Sensor.Value.Unit.DegreesC"
104 // "Scale" x -3
Patrick Venture863b9242018-03-08 08:29:23 -0800105
Patrick Venture0d73b102018-05-09 10:29:42 -0700106 // If no error was set, the values should all be there.
James Feistc065cf12018-07-05 10:23:11 -0700107 auto findUnit = propMap.find("Unit");
108 if (findUnit != propMap.end())
109 {
James Feist1f802f52019-02-08 13:51:43 -0800110 prop->unit = std::get<std::string>(findUnit->second);
James Feistc065cf12018-07-05 10:23:11 -0700111 }
112 auto findScale = propMap.find("Scale");
James Feist75eb7692019-02-25 12:50:02 -0800113 auto findMax = propMap.find("MaxValue");
114 auto findMin = propMap.find("MinValue");
115
116 prop->min = 0;
117 prop->max = 0;
118 prop->scale = 0;
James Feistc065cf12018-07-05 10:23:11 -0700119 if (findScale != propMap.end())
120 {
James Feist1f802f52019-02-08 13:51:43 -0800121 prop->scale = std::get<int64_t>(findScale->second);
James Feistc065cf12018-07-05 10:23:11 -0700122 }
James Feist75eb7692019-02-25 12:50:02 -0800123 if (findMax != propMap.end())
James Feistc065cf12018-07-05 10:23:11 -0700124 {
James Feist75eb7692019-02-25 12:50:02 -0800125 prop->max = std::visit(VariantToDoubleVisitor(), findMax->second);
126 }
127 if (findMin != propMap.end())
128 {
129 prop->min = std::visit(VariantToDoubleVisitor(), findMin->second);
James Feistc065cf12018-07-05 10:23:11 -0700130 }
131
James Feist1f802f52019-02-08 13:51:43 -0800132 prop->value = std::visit(VariantToDoubleVisitor(), propMap["Value"]);
Patrick Venture863b9242018-03-08 08:29:23 -0800133
134 return;
135}
136
Patrick Venture9b936922020-08-10 11:28:39 -0700137bool DbusHelper::thresholdsAsserted(const std::string& service,
James Feist36b7d8e2018-10-05 15:39:01 -0700138 const std::string& path)
139{
140
Patrick Venture8729eb92020-08-10 10:38:44 -0700141 auto critical = _bus.new_method_call(service.c_str(), path.c_str(),
142 propertiesintf, "GetAll");
James Feist36b7d8e2018-10-05 15:39:01 -0700143 critical.append(criticalThreshInf);
144 PropertyMap criticalMap;
145
146 try
147 {
Patrick Venture8729eb92020-08-10 10:38:44 -0700148 auto msg = _bus.call(critical);
Patrick Venture4fd8cff2018-10-31 14:24:12 -0700149 msg.read(criticalMap);
James Feist36b7d8e2018-10-05 15:39:01 -0700150 }
151 catch (sdbusplus::exception_t&)
152 {
153 // do nothing, sensors don't have to expose critical thresholds
154 return false;
155 }
156
157 auto findCriticalLow = criticalMap.find("CriticalAlarmLow");
158 auto findCriticalHigh = criticalMap.find("CriticalAlarmHigh");
159
160 bool asserted = false;
161 if (findCriticalLow != criticalMap.end())
162 {
James Feist1f802f52019-02-08 13:51:43 -0800163 asserted = std::get<bool>(findCriticalLow->second);
James Feist36b7d8e2018-10-05 15:39:01 -0700164 }
165
166 // as we are catching properties changed, a sensor could theoretically jump
167 // from one threshold to the other in one event, so check both thresholds
168 if (!asserted && findCriticalHigh != criticalMap.end())
169 {
James Feist1f802f52019-02-08 13:51:43 -0800170 asserted = std::get<bool>(findCriticalHigh->second);
James Feist36b7d8e2018-10-05 15:39:01 -0700171 }
172 return asserted;
173}
174
Patrick Venturea0764872020-08-08 07:48:43 -0700175} // namespace pid_control