Tao Lin | f2e9422 | 2023-10-31 17:38:17 +0800 | [diff] [blame] | 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 | |
| 20 | DbusSensor::DbusSensor(sdbusplus::bus_t& bus, const std::string& path, |
| 21 | VirtualSensor& virtualSensor) : |
Patrick Williams | 150d5f6 | 2024-08-16 15:21:45 -0400 | [diff] [blame] | 22 | bus(bus), path(path), virtualSensor(virtualSensor), |
Tao Lin | f2e9422 | 2023-10-31 17:38:17 +0800 | [diff] [blame] | 23 | signalPropChange( |
| 24 | bus, sdbusplus::bus::match::rules::propertiesChanged(path, sensorIntf), |
| 25 | [this](sdbusplus::message_t& message) { |
Patrick Williams | 150d5f6 | 2024-08-16 15:21:45 -0400 | [diff] [blame] | 26 | handleDbusSignalPropChange(message); |
| 27 | }), |
Tao Lin | f2e9422 | 2023-10-31 17:38:17 +0800 | [diff] [blame] | 28 | signalRemove( |
| 29 | bus, |
| 30 | sdbusplus::bus::match::rules::interfacesRemoved(interfacesSensorPath), |
| 31 | [this](sdbusplus::message_t& message) { |
Patrick Williams | 150d5f6 | 2024-08-16 15:21:45 -0400 | [diff] [blame] | 32 | handleDbusSignalRemove(message); |
| 33 | }) |
Tao Lin | f2e9422 | 2023-10-31 17:38:17 +0800 | [diff] [blame] | 34 | { |
| 35 | initSensorValue(); |
| 36 | } |
| 37 | |
| 38 | double DbusSensor::getSensorValue() |
| 39 | { |
| 40 | return value; |
| 41 | } |
| 42 | |
| 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) { |
Patrick Williams | 150d5f6 | 2024-08-16 15:21:45 -0400 | [diff] [blame] | 62 | handleDbusSignalNameOwnerChanged(message); |
| 63 | }); |
Tao Lin | f2e9422 | 2023-10-31 17:38:17 +0800 | [diff] [blame] | 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 | |
| 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 | |
| 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 | |
| 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 |