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