blob: 91cc840911ac28e7dbd3c067fa43f272c5bcbf3d [file] [log] [blame]
Patrick Venture863b9242018-03-08 08:29:23 -08001#include <iostream>
Patrick Venture0ef1faf2018-06-13 12:50:53 -07002#include <set>
Patrick Venture863b9242018-03-08 08:29:23 -08003
4#include "dbus/util.hpp"
5
6using Property = std::string;
7using Value = sdbusplus::message::variant<int64_t, std::string>;
8using 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{
17 auto mapper = bus.new_method_call(
18 "xyz.openbmc_project.ObjectMapper",
19 "/xyz/openbmc_project/object_mapper",
20 "xyz.openbmc_project.ObjectMapper",
21 "GetObject");
22
23 mapper.append(path);
24 mapper.append(std::vector<std::string>({intf}));
25
26 auto responseMsg = bus.call(mapper);
27 if (responseMsg.is_method_error())
28 {
29 throw std::runtime_error("ObjectMapper Call Failure");
30 }
31
32 std::map<std::string, std::vector<std::string>> response;
33 responseMsg.read(response);
34
35 if (response.begin() == response.end())
36 {
37 throw std::runtime_error("Unable to find Object: " + path);
38 }
39
40 return response.begin()->first;
41}
42
Patrick Venture0df7c0f2018-06-13 09:02:13 -070043void DbusHelper::GetProperties(sdbusplus::bus::bus& bus,
44 const std::string& service,
45 const std::string& path,
46 struct SensorProperties* prop)
Patrick Venture863b9242018-03-08 08:29:23 -080047{
Patrick Venture863b9242018-03-08 08:29:23 -080048 auto pimMsg = bus.new_method_call(service.c_str(),
49 path.c_str(),
50 propertiesintf.c_str(),
51 "GetAll");
52
53 pimMsg.append(sensorintf);
54 auto valueResponseMsg = bus.call(pimMsg);
55
56 if (valueResponseMsg.is_method_error())
57 {
58 std::cerr << "Error in value call\n";
59 throw std::runtime_error("ERROR in value call.");
60 }
61
62 // The PropertyMap returned will look like this because it's always
63 // reading a Sensor.Value interface.
64 // a{sv} 3:
65 // "Value" x 24875
66 // "Unit" s "xyz.openbmc_project.Sensor.Value.Unit.DegreesC"
67 // "Scale" x -3
68 PropertyMap propMap;
69 valueResponseMsg.read(propMap);
70
Patrick Venture0d73b102018-05-09 10:29:42 -070071 // If no error was set, the values should all be there.
Patrick Venture0df7c0f2018-06-13 09:02:13 -070072 prop->unit = sdbusplus::message::variant_ns::get<std::string>(
73 propMap["Unit"]);
74 prop->scale = sdbusplus::message::variant_ns::get<int64_t>(
75 propMap["Scale"]);
76 prop->value = sdbusplus::message::variant_ns::get<int64_t>(
77 propMap["Value"]);
Patrick Venture863b9242018-03-08 08:29:23 -080078
79 return;
80}
81
82std::string GetSensorPath(const std::string& type, const std::string& id)
83{
84 std::string layer = type;
85 if (type == "fan")
86 {
87 layer = "fan_tach";
88 }
89 else if (type == "temp")
90 {
91 layer = "temperature";
92 }
93 else
94 {
95 layer = "unknown"; // TODO(venture): Need to handle.
96 }
97
98 return std::string("/xyz/openbmc_project/sensors/" + layer + "/" + id);
99}
100
101std::string GetMatch(const std::string& type, const std::string& id)
102{
103 return std::string("type='signal',"
104 "interface='org.freedesktop.DBus.Properties',"
105 "member='PropertiesChanged',"
106 "path='" + GetSensorPath(type, id) + "'");
107}
108
Patrick Venture0ef1faf2018-06-13 12:50:53 -0700109bool ValidType(const std::string& type)
110{
111 static std::set<std::string> valid = {"fan", "temp"};
112 return (valid.find(type) != valid.end());
113}