blob: 1b9c6c32758993ca9c9e8512286f308335ae7262 [file] [log] [blame]
Gilbert Chen77e6fe72024-08-06 09:23:30 +00001#include "event_manager.hpp"
2
3#include "libpldm/utils.h"
4
5#include "terminus_manager.hpp"
6
7#include <phosphor-logging/lg2.hpp>
8#include <xyz/openbmc_project/Logging/Entry/server.hpp>
9
10#include <cerrno>
11#include <memory>
12
13PHOSPHOR_LOG2_USING;
14
15namespace pldm
16{
17namespace platform_mc
18{
19namespace fs = std::filesystem;
20
21int EventManager::handlePlatformEvent(
22 pldm_tid_t tid, uint16_t eventId, uint8_t eventClass,
23 const uint8_t* eventData, size_t eventDataSize)
24{
25 /* EventClass sensorEvent `Table 11 - PLDM Event Types` DSP0248 */
26 if (eventClass == PLDM_SENSOR_EVENT)
27 {
28 uint16_t sensorId = 0;
29 uint8_t sensorEventClassType = 0;
30 size_t eventClassDataOffset = 0;
31 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
32 &sensorEventClassType,
33 &eventClassDataOffset);
34 if (rc)
35 {
36 lg2::error(
37 "Failed to decode sensor event data from terminus ID {TID}, event class {CLASS}, event ID {EVENTID} with return code {RC}.",
38 "TID", tid, "CLASS", eventClass, "EVENTID", eventId, "RC", rc);
39 return rc;
40 }
41 switch (sensorEventClassType)
42 {
43 case PLDM_NUMERIC_SENSOR_STATE:
44 {
45 const uint8_t* sensorData = eventData + eventClassDataOffset;
46 size_t sensorDataLength = eventDataSize - eventClassDataOffset;
47 return processNumericSensorEvent(tid, sensorId, sensorData,
48 sensorDataLength);
49 }
50 case PLDM_STATE_SENSOR_STATE:
51 case PLDM_SENSOR_OP_STATE:
52 default:
53 lg2::info(
54 "Unsupported class type {CLASSTYPE} for the sensor event from terminus ID {TID} sensorId {SID}",
55 "CLASSTYPE", sensorEventClassType, "TID", tid, "SID",
56 sensorId);
57 return PLDM_ERROR;
58 }
59 }
60
61 lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE", eventClass);
62
63 return PLDM_ERROR;
64}
65
66int EventManager::processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
67 const uint8_t* sensorData,
68 size_t sensorDataLength)
69{
70 uint8_t eventState = 0;
71 uint8_t previousEventState = 0;
72 uint8_t sensorDataSize = 0;
73 uint32_t presentReading;
74 auto rc = decode_numeric_sensor_data(
75 sensorData, sensorDataLength, &eventState, &previousEventState,
76 &sensorDataSize, &presentReading);
77 if (rc)
78 {
79 lg2::error(
80 "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ",
81 "TID", tid, "RC", rc);
82 return rc;
83 }
84
85 double value = static_cast<double>(presentReading);
86 lg2::error(
87 "processNumericSensorEvent tid {TID}, sensorID {SID} value {VAL} previousState {PSTATE} eventState {ESTATE}",
88 "TID", tid, "SID", sensorId, "VAL", value, "PSTATE", previousEventState,
89 "ESTATE", eventState);
90
91 if (!termini.contains(tid) || !termini[tid])
92 {
93 lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
94 tid);
95 return PLDM_ERROR;
96 }
97
98 auto& terminus = termini[tid];
99
100 auto sensor = terminus->getSensorObject(sensorId);
101 if (!sensor)
102 {
103 lg2::error(
104 "Terminus ID {TID} has no sensor object with sensor ID {SID}.",
105 "TID", tid, "SID", sensorId);
106 return PLDM_ERROR;
107 }
108
109 switch (previousEventState)
110 {
111 case PLDM_SENSOR_UNKNOWN:
112 case PLDM_SENSOR_NORMAL:
113 {
114 switch (eventState)
115 {
116 case PLDM_SENSOR_UPPERFATAL:
117 case PLDM_SENSOR_UPPERCRITICAL:
118 {
119 sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
120 pldm::utils::Direction::HIGH,
121 value, true, true);
122 return sensor->triggerThresholdEvent(
123 pldm::utils::Level::CRITICAL,
124 pldm::utils::Direction::HIGH, value, true, true);
125 }
126 case PLDM_SENSOR_UPPERWARNING:
127 {
128 return sensor->triggerThresholdEvent(
129 pldm::utils::Level::WARNING,
130 pldm::utils::Direction::HIGH, value, true, true);
131 }
132 case PLDM_SENSOR_NORMAL:
133 break;
134 case PLDM_SENSOR_LOWERWARNING:
135 {
136 return sensor->triggerThresholdEvent(
137 pldm::utils::Level::WARNING,
138 pldm::utils::Direction::LOW, value, true, true);
139 }
140 case PLDM_SENSOR_LOWERCRITICAL:
141 case PLDM_SENSOR_LOWERFATAL:
142 {
143 sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
144 pldm::utils::Direction::LOW,
145 value, true, true);
146 return sensor->triggerThresholdEvent(
147 pldm::utils::Level::CRITICAL,
148 pldm::utils::Direction::LOW, value, true, true);
149 }
150 default:
151 break;
152 }
153 break;
154 }
155 case PLDM_SENSOR_LOWERWARNING:
156 {
157 switch (eventState)
158 {
159 case PLDM_SENSOR_UPPERFATAL:
160 case PLDM_SENSOR_UPPERCRITICAL:
161 break;
162 case PLDM_SENSOR_UPPERWARNING:
163 {
164 sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
165 pldm::utils::Direction::LOW,
166 value, false, false);
167 return sensor->triggerThresholdEvent(
168 pldm::utils::Level::WARNING,
169 pldm::utils::Direction::HIGH, value, true, true);
170 }
171 case PLDM_SENSOR_NORMAL:
172 {
173 return sensor->triggerThresholdEvent(
174 pldm::utils::Level::WARNING,
175 pldm::utils::Direction::LOW, value, false, false);
176 }
177 case PLDM_SENSOR_LOWERWARNING:
178 break;
179 case PLDM_SENSOR_LOWERCRITICAL:
180 case PLDM_SENSOR_LOWERFATAL:
181 {
182 return sensor->triggerThresholdEvent(
183 pldm::utils::Level::CRITICAL,
184 pldm::utils::Direction::LOW, value, true, true);
185 }
186 default:
187 break;
188 }
189 break;
190 }
191 case PLDM_SENSOR_LOWERCRITICAL:
192 case PLDM_SENSOR_LOWERFATAL:
193 {
194 switch (eventState)
195 {
196 case PLDM_SENSOR_UPPERFATAL:
197 case PLDM_SENSOR_UPPERCRITICAL:
198 case PLDM_SENSOR_UPPERWARNING:
199 break;
200 case PLDM_SENSOR_NORMAL:
201 {
202 sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
203 pldm::utils::Direction::LOW,
204 value, false, false);
205 sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
206 pldm::utils::Direction::LOW,
207 value, true, true);
208 return sensor->triggerThresholdEvent(
209 pldm::utils::Level::WARNING,
210 pldm::utils::Direction::LOW, value, false, false);
211 }
212 case PLDM_SENSOR_LOWERWARNING:
213 {
214 sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
215 pldm::utils::Direction::LOW,
216 value, false, false);
217 return sensor->triggerThresholdEvent(
218 pldm::utils::Level::WARNING,
219 pldm::utils::Direction::LOW, value, true, true);
220 }
221 case PLDM_SENSOR_LOWERCRITICAL:
222 case PLDM_SENSOR_LOWERFATAL:
223 default:
224 break;
225 }
226 break;
227 }
228 case PLDM_SENSOR_UPPERFATAL:
229 case PLDM_SENSOR_UPPERCRITICAL:
230 {
231 switch (eventState)
232 {
233 case PLDM_SENSOR_UPPERFATAL:
234 case PLDM_SENSOR_UPPERCRITICAL:
235 break;
236 case PLDM_SENSOR_UPPERWARNING:
237 {
238 sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
239 pldm::utils::Direction::HIGH,
240 value, false, false);
241 return sensor->triggerThresholdEvent(
242 pldm::utils::Level::WARNING,
243 pldm::utils::Direction::HIGH, value, true, true);
244 }
245 case PLDM_SENSOR_NORMAL:
246 {
247 sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
248 pldm::utils::Direction::HIGH,
249 value, false, false);
250 sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
251 pldm::utils::Direction::HIGH,
252 value, true, true);
253 return sensor->triggerThresholdEvent(
254 pldm::utils::Level::WARNING,
255 pldm::utils::Direction::HIGH, value, false, false);
256 }
257 case PLDM_SENSOR_LOWERWARNING:
258 case PLDM_SENSOR_LOWERCRITICAL:
259 case PLDM_SENSOR_LOWERFATAL:
260 default:
261 break;
262 }
263 break;
264 }
265 case PLDM_SENSOR_UPPERWARNING:
266 {
267 switch (eventState)
268 {
269 case PLDM_SENSOR_UPPERFATAL:
270 case PLDM_SENSOR_UPPERCRITICAL:
271 {
272 return sensor->triggerThresholdEvent(
273 pldm::utils::Level::CRITICAL,
274 pldm::utils::Direction::HIGH, value, true, true);
275 }
276 case PLDM_SENSOR_UPPERWARNING:
277 break;
278 case PLDM_SENSOR_NORMAL:
279 {
280 return sensor->triggerThresholdEvent(
281 pldm::utils::Level::WARNING,
282 pldm::utils::Direction::HIGH, value, false, false);
283 }
284 case PLDM_SENSOR_LOWERWARNING:
285 {
286 sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
287 pldm::utils::Direction::HIGH,
288 value, false, false);
289 return sensor->triggerThresholdEvent(
290 pldm::utils::Level::WARNING,
291 pldm::utils::Direction::LOW, value, true, true);
292 }
293 case PLDM_SENSOR_LOWERCRITICAL:
294 case PLDM_SENSOR_LOWERFATAL:
295 default:
296 break;
297 }
298 break;
299 }
300 default:
301 break;
302 }
303
304 return PLDM_SUCCESS;
305}
306
307} // namespace platform_mc
308} // namespace pldm