blob: f79bf4fbfd06f66bc14beed772098e252a8ea146 [file] [log] [blame]
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07001#include "dbus/util.hpp"
2
Patrick Venture863b9242018-03-08 08:29:23 -08003#include <iostream>
Patrick Venture0ef1faf2018-06-13 12:50:53 -07004#include <set>
Patrick Venture863b9242018-03-08 08:29:23 -08005
Patrick Venture863b9242018-03-08 08:29:23 -08006using Property = std::string;
James Feistc065cf12018-07-05 10:23:11 -07007using Value = sdbusplus::message::variant<int64_t, double, std::string>;
Patrick Venture863b9242018-03-08 08:29:23 -08008using PropertyMap = std::map<Property, Value>;
9
10/* TODO(venture): Basically all phosphor apps need this, maybe it should be a
11 * part of sdbusplus. There is an old version in libmapper.
12 */
Patrick Venture0df7c0f2018-06-13 09:02:13 -070013std::string DbusHelper::GetService(sdbusplus::bus::bus& bus,
14 const std::string& intf,
15 const std::string& path)
Patrick Venture863b9242018-03-08 08:29:23 -080016{
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070017 auto mapper =
18 bus.new_method_call("xyz.openbmc_project.ObjectMapper",
19 "/xyz/openbmc_project/object_mapper",
20 "xyz.openbmc_project.ObjectMapper", "GetObject");
Patrick Venture863b9242018-03-08 08:29:23 -080021
22 mapper.append(path);
23 mapper.append(std::vector<std::string>({intf}));
24
25 auto responseMsg = bus.call(mapper);
26 if (responseMsg.is_method_error())
27 {
28 throw std::runtime_error("ObjectMapper Call Failure");
29 }
30
31 std::map<std::string, std::vector<std::string>> response;
32 responseMsg.read(response);
33
34 if (response.begin() == response.end())
35 {
36 throw std::runtime_error("Unable to find Object: " + path);
37 }
38
39 return response.begin()->first;
40}
41
Patrick Venture0df7c0f2018-06-13 09:02:13 -070042void DbusHelper::GetProperties(sdbusplus::bus::bus& bus,
43 const std::string& service,
44 const std::string& path,
45 struct SensorProperties* prop)
Patrick Venture863b9242018-03-08 08:29:23 -080046{
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070047 auto pimMsg = bus.new_method_call(service.c_str(), path.c_str(),
48 propertiesintf.c_str(), "GetAll");
Patrick Venture863b9242018-03-08 08:29:23 -080049
50 pimMsg.append(sensorintf);
51 auto valueResponseMsg = bus.call(pimMsg);
52
53 if (valueResponseMsg.is_method_error())
54 {
55 std::cerr << "Error in value call\n";
56 throw std::runtime_error("ERROR in value call.");
57 }
58
59 // The PropertyMap returned will look like this because it's always
60 // reading a Sensor.Value interface.
61 // a{sv} 3:
62 // "Value" x 24875
63 // "Unit" s "xyz.openbmc_project.Sensor.Value.Unit.DegreesC"
64 // "Scale" x -3
65 PropertyMap propMap;
66 valueResponseMsg.read(propMap);
67
Patrick Venture0d73b102018-05-09 10:29:42 -070068 // If no error was set, the values should all be there.
James Feistc065cf12018-07-05 10:23:11 -070069 auto findUnit = propMap.find("Unit");
70 if (findUnit != propMap.end())
71 {
72 prop->unit =
73 sdbusplus::message::variant_ns::get<std::string>(findUnit->second);
74 }
75 auto findScale = propMap.find("Scale");
76 if (findScale != propMap.end())
77 {
78 prop->scale =
79 sdbusplus::message::variant_ns::get<int64_t>(findScale->second);
80 }
81 else
82 {
83 prop->scale = 0;
84 }
85
86 prop->value =
87 mapbox::util::apply_visitor(VariantToDoubleVisitor(), propMap["Value"]);
Patrick Venture863b9242018-03-08 08:29:23 -080088
89 return;
90}
91
92std::string GetSensorPath(const std::string& type, const std::string& id)
93{
94 std::string layer = type;
95 if (type == "fan")
96 {
97 layer = "fan_tach";
98 }
99 else if (type == "temp")
100 {
101 layer = "temperature";
102 }
103 else
104 {
105 layer = "unknown"; // TODO(venture): Need to handle.
106 }
107
108 return std::string("/xyz/openbmc_project/sensors/" + layer + "/" + id);
109}
110
111std::string GetMatch(const std::string& type, const std::string& id)
112{
113 return std::string("type='signal',"
114 "interface='org.freedesktop.DBus.Properties',"
115 "member='PropertiesChanged',"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700116 "path='" +
117 GetSensorPath(type, id) + "'");
Patrick Venture863b9242018-03-08 08:29:23 -0800118}
119
Patrick Venture0ef1faf2018-06-13 12:50:53 -0700120bool ValidType(const std::string& type)
121{
122 static std::set<std::string> valid = {"fan", "temp"};
123 return (valid.find(type) != valid.end());
124}