blob: 692e9c591a182a1b1cb6c8eccc212c59ee068c43 [file] [log] [blame]
Patrick Venture863b9242018-03-08 08:29:23 -08001#include <iostream>
2
3#include "dbus/util.hpp"
4
5using Property = std::string;
6using Value = sdbusplus::message::variant<int64_t, std::string>;
7using PropertyMap = std::map<Property, Value>;
8
9/* TODO(venture): Basically all phosphor apps need this, maybe it should be a
10 * part of sdbusplus. There is an old version in libmapper.
11 */
12std::string GetService(sdbusplus::bus::bus& bus,
13 const std::string& intf,
14 const std::string& path)
15{
16 auto mapper = bus.new_method_call(
17 "xyz.openbmc_project.ObjectMapper",
18 "/xyz/openbmc_project/object_mapper",
19 "xyz.openbmc_project.ObjectMapper",
20 "GetObject");
21
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
42void GetProperties(sdbusplus::bus::bus& bus,
43 const std::string& service,
44 const std::string& path,
45 struct SensorProperties* prop)
46{
47
48 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
71 if (propMap.size() != 3)
72 {
73 throw std::runtime_error("ERROR in results, expected three properties");
74 }
75
76 prop->unit = sdbusplus::message::variant_ns::get<std::string>(propMap["Unit"]);
77 prop->scale = sdbusplus::message::variant_ns::get<int64_t>(propMap["Scale"]);
78 prop->value = sdbusplus::message::variant_ns::get<int64_t>(propMap["Value"]);
79
80 return;
81}
82
83std::string GetSensorPath(const std::string& type, const std::string& id)
84{
85 std::string layer = type;
86 if (type == "fan")
87 {
88 layer = "fan_tach";
89 }
90 else if (type == "temp")
91 {
92 layer = "temperature";
93 }
94 else
95 {
96 layer = "unknown"; // TODO(venture): Need to handle.
97 }
98
99 return std::string("/xyz/openbmc_project/sensors/" + layer + "/" + id);
100}
101
102std::string GetMatch(const std::string& type, const std::string& id)
103{
104 return std::string("type='signal',"
105 "interface='org.freedesktop.DBus.Properties',"
106 "member='PropertiesChanged',"
107 "path='" + GetSensorPath(type, id) + "'");
108}
109