blob: c04a4884ded11c8d4cd8a0567627f7096cdc66ce [file] [log] [blame]
Thu Nguyen3c5486d2024-08-01 08:03:08 +00001#pragma once
2
3#include "libpldm/platform.h"
4#include "libpldm/pldm.h"
5
6#include "common/types.hpp"
Gilbert Chen77e6fe72024-08-06 09:23:30 +00007#include "common/utils.hpp"
Thu Nguyen3c5486d2024-08-01 08:03:08 +00008
9#include <sdbusplus/server/object.hpp>
10#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Chau Lyd197f092023-11-06 07:29:06 +000011#include <xyz/openbmc_project/Inventory/Source/PLDM/Entity/server.hpp>
Thu Nguyen6d615f12024-04-24 05:02:03 +000012#include <xyz/openbmc_project/Metric/Value/server.hpp>
Thu Nguyen3c5486d2024-08-01 08:03:08 +000013#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
21namespace pldm
22{
23namespace platform_mc
24{
25
Thu Nguyen6d615f12024-04-24 05:02:03 +000026constexpr const char* SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value";
27constexpr const char* METRIC_VALUE_INTF = "xyz.openbmc_project.Metric.Value";
28
Thu Nguyen3c5486d2024-08-01 08:03:08 +000029using SensorUnit = sdbusplus::xyz::openbmc_project::Sensor::server::Value::Unit;
30using ValueIntf = sdbusplus::server::object_t<
31 sdbusplus::xyz::openbmc_project::Sensor::server::Value>;
Thu Nguyen6d615f12024-04-24 05:02:03 +000032using MetricUnit = sdbusplus::xyz::openbmc_project::Metric::server::Value::Unit;
33using MetricIntf = sdbusplus::server::object_t<
34 sdbusplus::xyz::openbmc_project::Metric::server::Value>;
Thu Nguyen3c5486d2024-08-01 08:03:08 +000035using ThresholdWarningIntf = sdbusplus::server::object_t<
36 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning>;
37using ThresholdCriticalIntf = sdbusplus::server::object_t<
38 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical>;
39using OperationalStatusIntf =
40 sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::State::
41 Decorator::server::OperationalStatus>;
42using AvailabilityIntf = sdbusplus::server::object_t<
43 sdbusplus::xyz::openbmc_project::State::Decorator::server::Availability>;
44using AssociationDefinitionsInft = sdbusplus::server::object_t<
45 sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
Chau Lyd197f092023-11-06 07:29:06 +000046using EntityIntf = sdbusplus::server::object_t<
47 sdbusplus::xyz::openbmc_project::Inventory::Source::PLDM::server::Entity>;
Thu Nguyen3c5486d2024-08-01 08:03:08 +000048
49/**
50 * @brief NumericSensor
51 *
52 * This class handles sensor reading updated by sensor manager and export
53 * status to D-Bus interface.
54 */
55class 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
Patrick Williams16c2a0a2024-08-16 15:20:59 -040066 ~NumericSensor() {};
Thu Nguyen3c5486d2024-08-01 08:03:08 +000067
Gilbert Cheneac61a42022-02-23 20:56:19 +000068 /** @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
Thu Nguyen3c5486d2024-08-01 08:03:08 +000077 /** @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
Gilbert Cheneac61a42022-02-23 20:56:19 +000092 /** @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 */
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 */
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 */
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 */
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 */
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
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000180 /** @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
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000194 /** @brief Terminus ID which the sensor belongs to */
195 pldm_tid_t tid;
196
197 /** @brief Sensor ID */
198 uint16_t sensorId;
199
Gilbert Cheneac61a42022-02-23 20:56:19 +0000200 /** @brief The time stamp since last getSensorReading command in usec */
201 uint64_t timeStamp;
202
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000203 /** @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
Amithash Prasad98256602024-12-19 14:02:30 -0800212 /** @brief Sensor Unit */
213 SensorUnit sensorUnit;
214
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000215 private:
Gilbert Cheneac61a42022-02-23 20:56:19 +0000216 /**
217 * @brief Check sensor reading if any threshold has been crossed and update
218 * Threshold interfaces accordingly
219 */
220 void updateThresholds();
221
Amithash Prasad98256602024-12-19 14:02:30 -0800222 /**
223 * @brief Update the object units based on the PDR baseUnit
224 */
225 void setSensorUnit(uint8_t baseUnit);
226
Chau Lyd197f092023-11-06 07:29:06 +0000227 /** @brief Create the sensor inventory path.
228 *
229 * @param[in] associationPath - sensor association path
230 * @param[in] sensorName - sensor name
231 * @param[in] entityType - sensor PDR entity type
232 * @param[in] entityInstanceNum - sensor PDR entity instance number
233 * @param[in] containerId - sensor PDR entity container ID
234 *
235 * @return True when success otherwise return False
236 */
237 inline bool createInventoryPath(
238 const std::string& associationPath, const std::string& sensorName,
239 const uint16_t entityType, const uint16_t entityInstanceNum,
240 const uint16_t containerId);
241
Thu Nguyen6d615f12024-04-24 05:02:03 +0000242 std::unique_ptr<MetricIntf> metricIntf = nullptr;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000243 std::unique_ptr<ValueIntf> valueIntf = nullptr;
244 std::unique_ptr<ThresholdWarningIntf> thresholdWarningIntf = nullptr;
245 std::unique_ptr<ThresholdCriticalIntf> thresholdCriticalIntf = nullptr;
246 std::unique_ptr<AvailabilityIntf> availabilityIntf = nullptr;
247 std::unique_ptr<OperationalStatusIntf> operationalStatusIntf = nullptr;
248 std::unique_ptr<AssociationDefinitionsInft> associationDefinitionsIntf =
249 nullptr;
Chau Lyd197f092023-11-06 07:29:06 +0000250 std::unique_ptr<EntityIntf> entityIntf = nullptr;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000251
252 /** @brief Amount of hysteresis associated with the sensor thresholds */
253 double hysteresis;
254
255 /** @brief The resolution of sensor in Units */
256 double resolution;
257
258 /** @brief A constant value that is added in as part of conversion process
259 * of converting a raw sensor reading to Units */
260 double offset;
261
262 /** @brief A power-of-10 multiplier for baseUnit */
263 int8_t baseUnitModifier;
Thu Nguyen6d615f12024-04-24 05:02:03 +0000264 bool useMetricInterface = false;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000265};
266} // namespace platform_mc
267} // namespace pldm