1 #pragma once 2 3 #include "common/types.hpp" 4 #include "common/utils.hpp" 5 6 #include <libpldm/platform.h> 7 #include <libpldm/pldm.h> 8 9 #include <sdbusplus/server/object.hpp> 10 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 11 #include <xyz/openbmc_project/Inventory/Source/PLDM/Entity/server.hpp> 12 #include <xyz/openbmc_project/Metric/Value/server.hpp> 13 #include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp> 14 #include <xyz/openbmc_project/Sensor/Threshold/HardShutdown/server.hpp> 15 #include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp> 16 #include <xyz/openbmc_project/Sensor/Value/server.hpp> 17 #include <xyz/openbmc_project/State/Decorator/Availability/server.hpp> 18 #include <xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp> 19 20 #include <string> 21 22 namespace pldm 23 { 24 namespace platform_mc 25 { 26 27 constexpr const char* SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value"; 28 constexpr const char* METRIC_VALUE_INTF = "xyz.openbmc_project.Metric.Value"; 29 30 using SensorUnit = sdbusplus::xyz::openbmc_project::Sensor::server::Value::Unit; 31 using ValueIntf = sdbusplus::server::object_t< 32 sdbusplus::xyz::openbmc_project::Sensor::server::Value>; 33 using MetricUnit = sdbusplus::xyz::openbmc_project::Metric::server::Value::Unit; 34 using MetricIntf = sdbusplus::server::object_t< 35 sdbusplus::xyz::openbmc_project::Metric::server::Value>; 36 using ThresholdWarningIntf = sdbusplus::server::object_t< 37 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning>; 38 using ThresholdCriticalIntf = sdbusplus::server::object_t< 39 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical>; 40 using ThresholdHardShutdownIntf = sdbusplus::server::object_t< 41 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::HardShutdown>; 42 using OperationalStatusIntf = 43 sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::State:: 44 Decorator::server::OperationalStatus>; 45 using AvailabilityIntf = sdbusplus::server::object_t< 46 sdbusplus::xyz::openbmc_project::State::Decorator::server::Availability>; 47 using AssociationDefinitionsInft = sdbusplus::server::object_t< 48 sdbusplus::xyz::openbmc_project::Association::server::Definitions>; 49 using EntityIntf = sdbusplus::server::object_t< 50 sdbusplus::xyz::openbmc_project::Inventory::Source::PLDM::server::Entity>; 51 52 /** 53 * @brief NumericSensor 54 * 55 * This class handles sensor reading updated by sensor manager and export 56 * status to D-Bus interface. 57 */ 58 class NumericSensor 59 { 60 public: 61 NumericSensor(const pldm_tid_t tid, const bool sensorDisabled, 62 std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr, 63 std::string& sensorName, std::string& associationPath); 64 65 NumericSensor(const pldm_tid_t tid, const bool sensorDisabled, 66 std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr, 67 std::string& sensorName, std::string& associationPath); 68 ~NumericSensor()69 ~NumericSensor() {}; 70 71 /** @brief The function called by Sensor Manager to set sensor to 72 * error status. 73 */ 74 void handleErrGetSensorReading(); 75 76 /** @brief Updating the sensor status to D-Bus interface 77 */ 78 void updateReading(bool available, bool functional, double value = 0); 79 80 /** @brief ConversionFormula is used to convert raw value to the unit 81 * specified in PDR 82 * 83 * @param[in] value - raw value 84 * @return double - converted value 85 */ 86 double conversionFormula(double value); 87 88 /** @brief UnitModifier is used to apply the unit modifier specified in PDR 89 * 90 * @param[in] value - raw value 91 * @return double - converted value 92 */ 93 double unitModifier(double value); 94 95 /** @brief Check if value is over threshold. 96 * 97 * @param[in] alarm - previous alarm state 98 * @param[in] direction - upper or lower threshold checking 99 * @param[in] value - raw value 100 * @param[in] threshold - threshold value 101 * @param[in] hyst - hysteresis value 102 * @return bool - new alarm state 103 */ 104 bool checkThreshold(bool alarm, bool direction, double value, 105 double threshold, double hyst); 106 107 /** @brief Updating the association to D-Bus interface 108 * @param[in] inventoryPath - inventory path of the entity 109 */ setInventoryPath(const std::string & inventoryPath)110 inline void setInventoryPath(const std::string& inventoryPath) 111 { 112 if (associationDefinitionsIntf) 113 { 114 associationDefinitionsIntf->associations( 115 {{"chassis", "all_sensors", inventoryPath}}); 116 } 117 } 118 119 /** @brief Get Upper Critical threshold 120 * 121 * @return double - Upper Critical threshold 122 */ getThresholdUpperCritical()123 double getThresholdUpperCritical() 124 { 125 if (thresholdCriticalIntf) 126 { 127 return thresholdCriticalIntf->criticalHigh(); 128 } 129 else 130 { 131 return std::numeric_limits<double>::quiet_NaN(); 132 } 133 }; 134 135 /** @brief Get Lower Critical threshold 136 * 137 * @return double - Lower Critical threshold 138 */ getThresholdLowerCritical()139 double getThresholdLowerCritical() 140 { 141 if (thresholdCriticalIntf) 142 { 143 return thresholdCriticalIntf->criticalLow(); 144 } 145 else 146 { 147 return std::numeric_limits<double>::quiet_NaN(); 148 } 149 }; 150 151 /** @brief Get Upper Warning threshold 152 * 153 * @return double - Upper Warning threshold 154 */ getThresholdUpperWarning()155 double getThresholdUpperWarning() 156 { 157 if (thresholdWarningIntf) 158 { 159 return thresholdWarningIntf->warningHigh(); 160 } 161 else 162 { 163 return std::numeric_limits<double>::quiet_NaN(); 164 } 165 }; 166 167 /** @brief Get Lower Warning threshold 168 * 169 * @return double - Lower Warning threshold 170 */ getThresholdLowerWarning()171 double getThresholdLowerWarning() 172 { 173 if (thresholdWarningIntf) 174 { 175 return thresholdWarningIntf->warningLow(); 176 } 177 else 178 { 179 return std::numeric_limits<double>::quiet_NaN(); 180 } 181 }; 182 183 /** @brief Get Upper HardShutdown threshold 184 * 185 * @return double - Upper HardShutdown threshold 186 */ getThresholdUpperHardShutdown()187 double getThresholdUpperHardShutdown() 188 { 189 if (thresholdHardShutdownIntf) 190 { 191 return thresholdHardShutdownIntf->hardShutdownHigh(); 192 } 193 else 194 { 195 return std::numeric_limits<double>::quiet_NaN(); 196 } 197 }; 198 199 /** @brief Get Lower HardShutdown threshold 200 * 201 * @return double - Lower HardShutdown threshold 202 */ getThresholdLowerHardShutdownl()203 double getThresholdLowerHardShutdownl() 204 { 205 if (thresholdHardShutdownIntf) 206 { 207 return thresholdHardShutdownIntf->hardShutdownLow(); 208 } 209 else 210 { 211 return std::numeric_limits<double>::quiet_NaN(); 212 } 213 }; 214 215 /** @brief Check if value is over threshold. 216 * 217 * @param[in] eventType - event level in pldm::utils::Level 218 * @param[in] direction - direction type in pldm::utils::Direction 219 * @param[in] rawValue - sensor raw value 220 * @param[in] newAlarm - trigger alarm true/false 221 * @param[in] assert - event type asserted/deasserted 222 * 223 * @return PLDM completion code 224 */ 225 int triggerThresholdEvent(pldm::utils::Level eventType, 226 pldm::utils::Direction direction, double rawValue, 227 bool newAlarm, bool assert); 228 229 /** @brief Terminus ID which the sensor belongs to */ 230 pldm_tid_t tid; 231 232 /** @brief Sensor ID */ 233 uint16_t sensorId; 234 235 /** @brief The time stamp since last getSensorReading command in usec */ 236 uint64_t timeStamp; 237 238 /** @brief The time of sensor update interval in usec */ 239 uint64_t updateTime; 240 241 /** @brief sensorName */ 242 std::string sensorName; 243 244 /** @brief sensorNameSpace */ 245 std::string sensorNameSpace; 246 247 /** @brief Sensor Unit */ 248 SensorUnit sensorUnit; 249 250 private: 251 /** 252 * @brief Check sensor reading if any threshold has been crossed and update 253 * Threshold interfaces accordingly 254 */ 255 void updateThresholds(); 256 257 /** 258 * @brief Update the object units based on the PDR baseUnit 259 */ 260 void setSensorUnit(uint8_t baseUnit); 261 262 /** @brief Create the sensor inventory path. 263 * 264 * @param[in] associationPath - sensor association path 265 * @param[in] sensorName - sensor name 266 * @param[in] entityType - sensor PDR entity type 267 * @param[in] entityInstanceNum - sensor PDR entity instance number 268 * @param[in] containerId - sensor PDR entity container ID 269 * 270 * @return True when success otherwise return False 271 */ 272 inline bool createInventoryPath( 273 const std::string& associationPath, const std::string& sensorName, 274 const uint16_t entityType, const uint16_t entityInstanceNum, 275 const uint16_t containerId); 276 277 std::unique_ptr<MetricIntf> metricIntf = nullptr; 278 std::unique_ptr<ValueIntf> valueIntf = nullptr; 279 std::unique_ptr<ThresholdWarningIntf> thresholdWarningIntf = nullptr; 280 std::unique_ptr<ThresholdCriticalIntf> thresholdCriticalIntf = nullptr; 281 std::unique_ptr<ThresholdHardShutdownIntf> thresholdHardShutdownIntf = 282 nullptr; 283 std::unique_ptr<AvailabilityIntf> availabilityIntf = nullptr; 284 std::unique_ptr<OperationalStatusIntf> operationalStatusIntf = nullptr; 285 std::unique_ptr<AssociationDefinitionsInft> associationDefinitionsIntf = 286 nullptr; 287 std::unique_ptr<EntityIntf> entityIntf = nullptr; 288 289 /** @brief Amount of hysteresis associated with the sensor thresholds */ 290 double hysteresis; 291 292 /** @brief The resolution of sensor in Units */ 293 double resolution; 294 295 /** @brief A constant value that is added in as part of conversion process 296 * of converting a raw sensor reading to Units */ 297 double offset; 298 299 /** @brief A power-of-10 multiplier for baseUnit */ 300 int8_t baseUnitModifier; 301 bool useMetricInterface = false; 302 }; 303 } // namespace platform_mc 304 } // namespace pldm 305