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