| #include "dbusSensor.hpp" | 
 |  | 
 | #include "virtualSensor.hpp" | 
 |  | 
 | #include <sdbusplus/bus.hpp> | 
 | #include <sdbusplus/bus/match.hpp> | 
 |  | 
 | #include <cmath> | 
 | static constexpr auto sensorIntf = | 
 |     sdbusplus::common::xyz::openbmc_project::sensor::Value::interface; | 
 |  | 
 | /** When the Entity Manager removes the sensor, the interfaceRemoveSignal sent | 
 |  * uses the path /xyz/openbmc_project/sensors | 
 |  * */ | 
 | static constexpr auto interfacesSensorPath = "/xyz/openbmc_project/sensors"; | 
 |  | 
 | namespace phosphor::virtual_sensor | 
 | { | 
 |  | 
 | DbusSensor::DbusSensor(sdbusplus::bus_t& bus, const std::string& path, | 
 |                        VirtualSensor& virtualSensor) : | 
 |     bus(bus), path(path), virtualSensor(virtualSensor), | 
 |     signalPropChange( | 
 |         bus, sdbusplus::bus::match::rules::propertiesChanged(path, sensorIntf), | 
 |         [this](sdbusplus::message_t& message) { | 
 |             handleDbusSignalPropChange(message); | 
 |         }), | 
 |     signalRemove( | 
 |         bus, | 
 |         sdbusplus::bus::match::rules::interfacesRemoved(interfacesSensorPath), | 
 |         [this](sdbusplus::message_t& message) { | 
 |             handleDbusSignalRemove(message); | 
 |         }) | 
 | { | 
 |     initSensorValue(); | 
 | } | 
 |  | 
 | double DbusSensor::getSensorValue() | 
 | { | 
 |     return value; | 
 | } | 
 |  | 
 | void DbusSensor::initSensorValue() | 
 | { | 
 |     try | 
 |     { | 
 |         // If servName is not empty, reduce one DbusCall | 
 |         if (servName.empty()) | 
 |         { | 
 |             value = std::numeric_limits<double>::quiet_NaN(); | 
 |             servName = getService(bus, path, sensorIntf); | 
 |         } | 
 |  | 
 |         if (!servName.empty()) | 
 |         { | 
 |             signalNameOwnerChanged.reset(); | 
 |             signalNameOwnerChanged = std::make_unique<sdbusplus::bus::match_t>( | 
 |                 bus, | 
 |                 sdbusplus::bus::match::rules::nameOwnerChanged() + | 
 |                     sdbusplus::bus::match::rules::arg0namespace(servName), | 
 |                 [this](sdbusplus::message_t& message) { | 
 |                     handleDbusSignalNameOwnerChanged(message); | 
 |                 }); | 
 |  | 
 |             value = getDbusProperty<double>(bus, servName, path, sensorIntf, | 
 |                                             "Value"); | 
 |         } | 
 |     } | 
 |     catch (const std::exception& e) | 
 |     { | 
 |         value = std::numeric_limits<double>::quiet_NaN(); | 
 |     } | 
 |  | 
 |     return; | 
 | } | 
 |  | 
 | void DbusSensor::handleDbusSignalNameOwnerChanged(sdbusplus::message_t& msg) | 
 | { | 
 |     try | 
 |     { | 
 |         auto [name, oldOwner, | 
 |               newOwner] = msg.unpack<std::string, std::string, std::string>(); | 
 |  | 
 |         if (!oldOwner.empty() && !name.empty()) | 
 |         { | 
 |             if (name == servName) | 
 |             { | 
 |                 // Connection removed | 
 |  | 
 |                 value = std::numeric_limits<double>::quiet_NaN(); | 
 |                 virtualSensor.updateVirtualSensor(); | 
 |             } | 
 |         } | 
 |     } | 
 |     catch (const std::exception& e) | 
 |     { | 
 |         lg2::error("Error in dbusSensor NameOwnerChanged: {PATH}  {ERROR}", | 
 |                    "PATH", path, "ERROR", e); | 
 |     } | 
 | } | 
 |  | 
 | void DbusSensor::handleDbusSignalPropChange(sdbusplus::message_t& msg) | 
 | { | 
 |     try | 
 |     { | 
 |         using SensorValuePropertiesVariant = sdbusplus::server::xyz:: | 
 |             openbmc_project::sensor::Value::PropertiesVariant; | 
 |         auto [msgIfce, msgData] = | 
 |             msg.unpack<std::string, | 
 |                        std::map<std::string, SensorValuePropertiesVariant>>(); | 
 |  | 
 |         std::string path = msg.get_path(); | 
 |  | 
 |         if (auto itr = msgData.find("Value"); itr != msgData.end()) | 
 |         { | 
 |             value = std::get<double>(itr->second); | 
 |             if (!std::isfinite(value)) | 
 |             { | 
 |                 value = std::numeric_limits<double>::quiet_NaN(); | 
 |             } | 
 |  | 
 |             virtualSensor.updateVirtualSensor(); | 
 |         } | 
 |     } | 
 |     catch (const std::exception& e) | 
 |     { | 
 |         lg2::error("Error in dbusSensor PropertyChange: {PATH}  {ERROR}", | 
 |                    "PATH", path, "ERROR", e); | 
 |     } | 
 | } | 
 |  | 
 | void DbusSensor::handleDbusSignalRemove(sdbusplus::message_t& msg) | 
 | { | 
 |     try | 
 |     { | 
 |         auto objPath = msg.unpack<sdbusplus::message::object_path>(); | 
 |  | 
 |         if (this->path == objPath) | 
 |         { | 
 |             value = std::numeric_limits<double>::quiet_NaN(); | 
 |             virtualSensor.updateVirtualSensor(); | 
 |         } | 
 |     } | 
 |     catch (const std::exception& e) | 
 |     { | 
 |         lg2::error("Error in dbusSensor interfaceRemove: {PATH}  {ERROR}", | 
 |                    "PATH", path, "ERROR", e); | 
 |     } | 
 | } | 
 |  | 
 | } // namespace phosphor::virtual_sensor |