blob: f79705bd964e5bc58ef78e23de600030ceb30537 [file] [log] [blame]
Tao Linf2e94222023-10-31 17:38:17 +08001#include "dbusSensor.hpp"
2
3#include "virtualSensor.hpp"
4
5#include <sdbusplus/bus.hpp>
6#include <sdbusplus/bus/match.hpp>
7
8#include <cmath>
9static constexpr auto sensorIntf =
10 sdbusplus::common::xyz::openbmc_project::sensor::Value::interface;
11
12/** When the Entity Manager removes the sensor, the interfaceRemoveSignal sent
13 * uses the path /xyz/openbmc_project/sensors
14 * */
15static constexpr auto interfacesSensorPath = "/xyz/openbmc_project/sensors";
16
17namespace phosphor::virtual_sensor
18{
19
20DbusSensor::DbusSensor(sdbusplus::bus_t& bus, const std::string& path,
21 VirtualSensor& virtualSensor) :
22 bus(bus),
23 path(path), virtualSensor(virtualSensor),
24 signalPropChange(
25 bus, sdbusplus::bus::match::rules::propertiesChanged(path, sensorIntf),
26 [this](sdbusplus::message_t& message) {
27 handleDbusSignalPropChange(message);
28}),
29 signalRemove(
30 bus,
31 sdbusplus::bus::match::rules::interfacesRemoved(interfacesSensorPath),
32 [this](sdbusplus::message_t& message) {
33 handleDbusSignalRemove(message);
34})
35{
36 initSensorValue();
37}
38
39double DbusSensor::getSensorValue()
40{
41 return value;
42}
43
44void DbusSensor::initSensorValue()
45{
46 try
47 {
48 // If servName is not empty, reduce one DbusCall
49 if (servName.empty())
50 {
51 value = std::numeric_limits<double>::quiet_NaN();
52 servName = getService(bus, path, sensorIntf);
53 }
54
55 if (!servName.empty())
56 {
57 signalNameOwnerChanged.reset();
58 signalNameOwnerChanged = std::make_unique<sdbusplus::bus::match_t>(
59 bus,
60 sdbusplus::bus::match::rules::nameOwnerChanged() +
61 sdbusplus::bus::match::rules::arg0namespace(servName),
62 [this](sdbusplus::message_t& message) {
63 handleDbusSignalNameOwnerChanged(message);
64 });
65
66 value = getDbusProperty<double>(bus, servName, path, sensorIntf,
67 "Value");
68 }
69 }
70 catch (const std::exception& e)
71 {
72 value = std::numeric_limits<double>::quiet_NaN();
73 }
74
75 return;
76}
77
78void DbusSensor::handleDbusSignalNameOwnerChanged(sdbusplus::message_t& msg)
79{
80 try
81 {
82 auto [name, oldOwner,
83 newOwner] = msg.unpack<std::string, std::string, std::string>();
84
85 if (!oldOwner.empty() && !name.empty())
86 {
87 if (name == servName)
88 {
89 // Connection removed
90
91 value = std::numeric_limits<double>::quiet_NaN();
92 virtualSensor.updateVirtualSensor();
93 }
94 }
95 }
96 catch (const std::exception& e)
97 {
98 lg2::error("Error in dbusSensor NameOwnerChanged: {PATH} {ERROR}",
99 "PATH", path, "ERROR", e);
100 }
101}
102
103void DbusSensor::handleDbusSignalPropChange(sdbusplus::message_t& msg)
104{
105 try
106 {
107 using SensorValuePropertiesVariant = sdbusplus::server::xyz::
108 openbmc_project::sensor::Value::PropertiesVariant;
109 auto [msgIfce, msgData] =
110 msg.unpack<std::string,
111 std::map<std::string, SensorValuePropertiesVariant>>();
112
113 std::string path = msg.get_path();
114
115 if (auto itr = msgData.find("Value"); itr != msgData.end())
116 {
117 value = std::get<double>(itr->second);
118 if (!std::isfinite(value))
119 {
120 value = std::numeric_limits<double>::quiet_NaN();
121 }
122
123 virtualSensor.updateVirtualSensor();
124 }
125 }
126 catch (const std::exception& e)
127 {
128 lg2::error("Error in dbusSensor PropertyChange: {PATH} {ERROR}",
129 "PATH", path, "ERROR", e);
130 }
131}
132
133void DbusSensor::handleDbusSignalRemove(sdbusplus::message_t& msg)
134{
135 try
136 {
137 auto objPath = msg.unpack<sdbusplus::message::object_path>();
138
139 if (this->path == objPath)
140 {
141 value = std::numeric_limits<double>::quiet_NaN();
142 virtualSensor.updateVirtualSensor();
143 }
144 }
145 catch (const std::exception& e)
146 {
147 lg2::error("Error in dbusSensor interfaceRemove: {PATH} {ERROR}",
148 "PATH", path, "ERROR", e);
149 }
150}
151
152} // namespace phosphor::virtual_sensor