blob: a55c51afbaa0f7eaa84b6a83d7d46c7ae49c6a4f [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
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000212 private:
Gilbert Cheneac61a42022-02-23 20:56:19 +0000213 /**
214 * @brief Check sensor reading if any threshold has been crossed and update
215 * Threshold interfaces accordingly
216 */
217 void updateThresholds();
218
Chau Lyd197f092023-11-06 07:29:06 +0000219 /** @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
Thu Nguyen6d615f12024-04-24 05:02:03 +0000234 std::unique_ptr<MetricIntf> metricIntf = nullptr;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000235 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;
Chau Lyd197f092023-11-06 07:29:06 +0000242 std::unique_ptr<EntityIntf> entityIntf = nullptr;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000243
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;
Thu Nguyen6d615f12024-04-24 05:02:03 +0000256 bool useMetricInterface = false;
Thu Nguyen3c5486d2024-08-01 08:03:08 +0000257};
258} // namespace platform_mc
259} // namespace pldm