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