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