1*a743e384SChau Ly #include "oem_event_manager.hpp"
2*a743e384SChau Ly
3*a743e384SChau Ly #include "requester/handler.hpp"
4*a743e384SChau Ly #include "requester/request.hpp"
5*a743e384SChau Ly
6*a743e384SChau Ly #include <config.h>
7*a743e384SChau Ly #include <libpldm/pldm.h>
8*a743e384SChau Ly #include <libpldm/utils.h>
9*a743e384SChau Ly #include <systemd/sd-journal.h>
10*a743e384SChau Ly
11*a743e384SChau Ly #include <phosphor-logging/lg2.hpp>
12*a743e384SChau Ly #include <xyz/openbmc_project/Logging/Entry/server.hpp>
13*a743e384SChau Ly
14*a743e384SChau Ly #include <algorithm>
15*a743e384SChau Ly #include <map>
16*a743e384SChau Ly #include <sstream>
17*a743e384SChau Ly #include <string>
18*a743e384SChau Ly #include <unordered_map>
19*a743e384SChau Ly
20*a743e384SChau Ly namespace pldm
21*a743e384SChau Ly {
22*a743e384SChau Ly namespace oem_ampere
23*a743e384SChau Ly {
24*a743e384SChau Ly namespace boot_stage = boot::stage;
25*a743e384SChau Ly
26*a743e384SChau Ly constexpr const char* BIOSFWPanicRegistry =
27*a743e384SChau Ly "OpenBMC.0.1.BIOSFirmwarePanicReason.Warning";
28*a743e384SChau Ly constexpr auto maxDIMMIdxBitNum = 24;
29*a743e384SChau Ly
30*a743e384SChau Ly /*
31*a743e384SChau Ly An array of possible boot status of a boot stage.
32*a743e384SChau Ly The index maps with byte 0 of boot code.
33*a743e384SChau Ly */
34*a743e384SChau Ly std::array<std::string, 3> bootStatMsg = {" booting", " completed", " failed"};
35*a743e384SChau Ly
36*a743e384SChau Ly /*
37*a743e384SChau Ly An array of possible boot status of DDR training stage.
38*a743e384SChau Ly The index maps with byte 0 of boot code.
39*a743e384SChau Ly */
40*a743e384SChau Ly std::array<std::string, 3> ddrTrainingMsg = {
41*a743e384SChau Ly " progress started", " in-progress", " progress completed"};
42*a743e384SChau Ly
43*a743e384SChau Ly /*
44*a743e384SChau Ly In Ampere systems, BMC only directly communicates with MCTP/PLDM SoC
45*a743e384SChau Ly EPs through SMBus and PCIe. When host boots up, SMBUS interface
46*a743e384SChau Ly comes up first. In this interface, BMC is bus owner.
47*a743e384SChau Ly
48*a743e384SChau Ly mctpd will set the EID 0x14 for S0 and 0x16 for S1 (if available).
49*a743e384SChau Ly pldmd will always use TID 1 for S0 and TID 2 for S1 (if available).
50*a743e384SChau Ly */
51*a743e384SChau Ly EventToMsgMap_t tidToSocketNameMap = {{1, "SOCKET 0"}, {2, "SOCKET 1"}};
52*a743e384SChau Ly
53*a743e384SChau Ly /*
54*a743e384SChau Ly A map between sensor IDs and their names in string.
55*a743e384SChau Ly Using pldm::oem::sensor_ids
56*a743e384SChau Ly */
57*a743e384SChau Ly EventToMsgMap_t sensorIdToStrMap = {{BOOT_OVERALL, "BOOT_OVERALL"}};
58*a743e384SChau Ly
59*a743e384SChau Ly /*
60*a743e384SChau Ly A map between the boot stages and logging strings.
61*a743e384SChau Ly Using pldm::oem::boot::stage::boot_stage
62*a743e384SChau Ly */
63*a743e384SChau Ly EventToMsgMap_t bootStageToMsgMap = {
64*a743e384SChau Ly {boot_stage::SECPRO, "SECpro"},
65*a743e384SChau Ly {boot_stage::MPRO, "Mpro"},
66*a743e384SChau Ly {boot_stage::ATF_BL1, "ATF BL1"},
67*a743e384SChau Ly {boot_stage::ATF_BL2, "ATF BL2"},
68*a743e384SChau Ly {boot_stage::DDR_INITIALIZATION, "DDR initialization"},
69*a743e384SChau Ly {boot_stage::DDR_TRAINING, "DDR training"},
70*a743e384SChau Ly {boot_stage::S0_DDR_TRAINING_FAILURE, "DDR training failure"},
71*a743e384SChau Ly {boot_stage::ATF_BL31, "ATF BL31"},
72*a743e384SChau Ly {boot_stage::ATF_BL32, "ATF BL32"},
73*a743e384SChau Ly {boot_stage::S1_DDR_TRAINING_FAILURE, "DDR training failure"},
74*a743e384SChau Ly {boot_stage::UEFI_STATUS_CLASS_CODE_MIN,
75*a743e384SChau Ly "ATF BL33 (UEFI) booting status = "}};
76*a743e384SChau Ly
77*a743e384SChau Ly /*
78*a743e384SChau Ly A map between log level and the registry used for Redfish SEL log
79*a743e384SChau Ly Using pldm::oem::log_level
80*a743e384SChau Ly */
81*a743e384SChau Ly std::unordered_map<log_level, std::string> logLevelToRedfishMsgIdMap = {
82*a743e384SChau Ly {log_level::BIOSFWPANIC, BIOSFWPanicRegistry}};
83*a743e384SChau Ly
84*a743e384SChau Ly std::string
prefixMsgStrCreation(pldm_tid_t tid,uint16_t sensorId)85*a743e384SChau Ly OemEventManager::prefixMsgStrCreation(pldm_tid_t tid, uint16_t sensorId)
86*a743e384SChau Ly {
87*a743e384SChau Ly std::string description;
88*a743e384SChau Ly if (!tidToSocketNameMap.contains(tid))
89*a743e384SChau Ly {
90*a743e384SChau Ly description += "TID " + std::to_string(tid) + ": ";
91*a743e384SChau Ly }
92*a743e384SChau Ly else
93*a743e384SChau Ly {
94*a743e384SChau Ly description += tidToSocketNameMap[tid] + ": ";
95*a743e384SChau Ly }
96*a743e384SChau Ly
97*a743e384SChau Ly if (!sensorIdToStrMap.contains(sensorId))
98*a743e384SChau Ly {
99*a743e384SChau Ly description += "Sensor ID " + std::to_string(sensorId) + ": ";
100*a743e384SChau Ly }
101*a743e384SChau Ly else
102*a743e384SChau Ly {
103*a743e384SChau Ly description += sensorIdToStrMap[sensorId] + ": ";
104*a743e384SChau Ly }
105*a743e384SChau Ly
106*a743e384SChau Ly return description;
107*a743e384SChau Ly }
108*a743e384SChau Ly
sendJournalRedfish(const std::string & description,log_level & logLevel)109*a743e384SChau Ly void OemEventManager::sendJournalRedfish(const std::string& description,
110*a743e384SChau Ly log_level& logLevel)
111*a743e384SChau Ly {
112*a743e384SChau Ly if (description.empty())
113*a743e384SChau Ly {
114*a743e384SChau Ly return;
115*a743e384SChau Ly }
116*a743e384SChau Ly
117*a743e384SChau Ly if (!logLevelToRedfishMsgIdMap.contains(logLevel))
118*a743e384SChau Ly {
119*a743e384SChau Ly lg2::error("Invalid {LEVEL} Description {DES}", "LEVEL", logLevel,
120*a743e384SChau Ly "DES", description);
121*a743e384SChau Ly return;
122*a743e384SChau Ly }
123*a743e384SChau Ly auto redfishMsgId = logLevelToRedfishMsgIdMap[logLevel];
124*a743e384SChau Ly lg2::info("MESSAGE={DES}", "DES", description, "REDFISH_MESSAGE_ID",
125*a743e384SChau Ly redfishMsgId, "REDFISH_MESSAGE_ARGS", description);
126*a743e384SChau Ly }
127*a743e384SChau Ly
dimmIdxsToString(uint32_t dimmIdxs)128*a743e384SChau Ly std::string OemEventManager::dimmIdxsToString(uint32_t dimmIdxs)
129*a743e384SChau Ly {
130*a743e384SChau Ly std::string description;
131*a743e384SChau Ly for (const auto bitIdx : std::views::iota(0, maxDIMMIdxBitNum))
132*a743e384SChau Ly {
133*a743e384SChau Ly if (dimmIdxs & (static_cast<uint32_t>(1) << bitIdx))
134*a743e384SChau Ly {
135*a743e384SChau Ly description += " #" + std::to_string(bitIdx);
136*a743e384SChau Ly }
137*a743e384SChau Ly }
138*a743e384SChau Ly return description;
139*a743e384SChau Ly }
140*a743e384SChau Ly
handleBootOverallEvent(pldm_tid_t,uint16_t,uint32_t presentReading)141*a743e384SChau Ly void OemEventManager::handleBootOverallEvent(
142*a743e384SChau Ly pldm_tid_t /*tid*/, uint16_t /*sensorId*/, uint32_t presentReading)
143*a743e384SChau Ly {
144*a743e384SChau Ly log_level logLevel{log_level::OK};
145*a743e384SChau Ly std::string description;
146*a743e384SChau Ly std::stringstream strStream;
147*a743e384SChau Ly
148*a743e384SChau Ly uint8_t byte0 = (presentReading & 0x000000ff);
149*a743e384SChau Ly uint8_t byte1 = (presentReading & 0x0000ff00) >> 8;
150*a743e384SChau Ly uint8_t byte2 = (presentReading & 0x00ff0000) >> 16;
151*a743e384SChau Ly uint8_t byte3 = (presentReading & 0xff000000) >> 24;
152*a743e384SChau Ly /*
153*a743e384SChau Ly * Handle SECpro, Mpro, ATF BL1, ATF BL2, ATF BL31,
154*a743e384SChau Ly * ATF BL32 and DDR initialization
155*a743e384SChau Ly */
156*a743e384SChau Ly if (bootStageToMsgMap.contains(byte3))
157*a743e384SChau Ly {
158*a743e384SChau Ly // Boot stage adding
159*a743e384SChau Ly description += bootStageToMsgMap[byte3];
160*a743e384SChau Ly
161*a743e384SChau Ly switch (byte3)
162*a743e384SChau Ly {
163*a743e384SChau Ly case boot_stage::DDR_TRAINING:
164*a743e384SChau Ly if (byte0 >= ddrTrainingMsg.size())
165*a743e384SChau Ly {
166*a743e384SChau Ly logLevel = log_level::BIOSFWPANIC;
167*a743e384SChau Ly description += " unknown status";
168*a743e384SChau Ly }
169*a743e384SChau Ly else
170*a743e384SChau Ly {
171*a743e384SChau Ly description += ddrTrainingMsg[byte0];
172*a743e384SChau Ly }
173*a743e384SChau Ly if (0x01 == byte0)
174*a743e384SChau Ly {
175*a743e384SChau Ly // Add complete percentage
176*a743e384SChau Ly description += " at " + std::to_string(byte1) + "%";
177*a743e384SChau Ly }
178*a743e384SChau Ly break;
179*a743e384SChau Ly case boot_stage::S0_DDR_TRAINING_FAILURE:
180*a743e384SChau Ly case boot_stage::S1_DDR_TRAINING_FAILURE:
181*a743e384SChau Ly // ddr_training_status_msg()
182*a743e384SChau Ly logLevel = log_level::BIOSFWPANIC;
183*a743e384SChau Ly description += " at DIMMs:";
184*a743e384SChau Ly // dimmIdxs = presentReading & 0x00ffffff;
185*a743e384SChau Ly description += dimmIdxsToString(presentReading & 0x00ffffff);
186*a743e384SChau Ly description += " of socket ";
187*a743e384SChau Ly description +=
188*a743e384SChau Ly (boot_stage::S0_DDR_TRAINING_FAILURE == byte3) ? "0" : "1";
189*a743e384SChau Ly break;
190*a743e384SChau Ly default:
191*a743e384SChau Ly if (byte0 >= bootStatMsg.size())
192*a743e384SChau Ly {
193*a743e384SChau Ly logLevel = log_level::BIOSFWPANIC;
194*a743e384SChau Ly description += " unknown status";
195*a743e384SChau Ly }
196*a743e384SChau Ly else
197*a743e384SChau Ly {
198*a743e384SChau Ly description += bootStatMsg[byte0];
199*a743e384SChau Ly }
200*a743e384SChau Ly break;
201*a743e384SChau Ly }
202*a743e384SChau Ly
203*a743e384SChau Ly // Sensor report action is fail
204*a743e384SChau Ly if (boot::status::BOOT_STATUS_FAILURE == byte2)
205*a743e384SChau Ly {
206*a743e384SChau Ly logLevel = log_level::BIOSFWPANIC;
207*a743e384SChau Ly }
208*a743e384SChau Ly }
209*a743e384SChau Ly else
210*a743e384SChau Ly {
211*a743e384SChau Ly if (byte3 <= boot_stage::UEFI_STATUS_CLASS_CODE_MAX)
212*a743e384SChau Ly {
213*a743e384SChau Ly description +=
214*a743e384SChau Ly bootStageToMsgMap[boot_stage::UEFI_STATUS_CLASS_CODE_MIN];
215*a743e384SChau Ly
216*a743e384SChau Ly strStream
217*a743e384SChau Ly << "Segment (0x" << std::setfill('0') << std::hex
218*a743e384SChau Ly << std::setw(8) << static_cast<uint32_t>(presentReading)
219*a743e384SChau Ly << "), Status Class (0x" << std::setw(2)
220*a743e384SChau Ly << static_cast<uint32_t>(byte3) << "), Status SubClass (0x"
221*a743e384SChau Ly << std::setw(2) << static_cast<uint32_t>(byte2)
222*a743e384SChau Ly << "), Operation Code (0x" << std::setw(4)
223*a743e384SChau Ly << static_cast<uint32_t>((presentReading & 0xffff0000) >> 16)
224*a743e384SChau Ly << ")" << std::dec;
225*a743e384SChau Ly
226*a743e384SChau Ly description += strStream.str();
227*a743e384SChau Ly }
228*a743e384SChau Ly }
229*a743e384SChau Ly
230*a743e384SChau Ly // Log to Redfish event
231*a743e384SChau Ly sendJournalRedfish(description, logLevel);
232*a743e384SChau Ly }
233*a743e384SChau Ly
processNumericSensorEvent(pldm_tid_t tid,uint16_t sensorId,const uint8_t * sensorData,size_t sensorDataLength)234*a743e384SChau Ly int OemEventManager::processNumericSensorEvent(
235*a743e384SChau Ly pldm_tid_t tid, uint16_t sensorId, const uint8_t* sensorData,
236*a743e384SChau Ly size_t sensorDataLength)
237*a743e384SChau Ly {
238*a743e384SChau Ly uint8_t eventState = 0;
239*a743e384SChau Ly uint8_t previousEventState = 0;
240*a743e384SChau Ly uint8_t sensorDataSize = 0;
241*a743e384SChau Ly uint32_t presentReading;
242*a743e384SChau Ly auto rc = decode_numeric_sensor_data(
243*a743e384SChau Ly sensorData, sensorDataLength, &eventState, &previousEventState,
244*a743e384SChau Ly &sensorDataSize, &presentReading);
245*a743e384SChau Ly if (rc)
246*a743e384SChau Ly {
247*a743e384SChau Ly lg2::error(
248*a743e384SChau Ly "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ",
249*a743e384SChau Ly "TID", tid, "RC", rc);
250*a743e384SChau Ly return rc;
251*a743e384SChau Ly }
252*a743e384SChau Ly
253*a743e384SChau Ly switch (sensorId)
254*a743e384SChau Ly {
255*a743e384SChau Ly case BOOT_OVERALL:
256*a743e384SChau Ly handleBootOverallEvent(tid, sensorId, presentReading);
257*a743e384SChau Ly break;
258*a743e384SChau Ly default:
259*a743e384SChau Ly std::string description;
260*a743e384SChau Ly std::stringstream strStream;
261*a743e384SChau Ly log_level logLevel = log_level::OK;
262*a743e384SChau Ly
263*a743e384SChau Ly description += "SENSOR_EVENT : NUMERIC_SENSOR_STATE: ";
264*a743e384SChau Ly description += prefixMsgStrCreation(tid, sensorId);
265*a743e384SChau Ly strStream << std::setfill('0') << std::hex << "eventState 0x"
266*a743e384SChau Ly << std::setw(2) << static_cast<uint32_t>(eventState)
267*a743e384SChau Ly << " previousEventState 0x" << std::setw(2)
268*a743e384SChau Ly << static_cast<uint32_t>(previousEventState)
269*a743e384SChau Ly << " sensorDataSize 0x" << std::setw(2)
270*a743e384SChau Ly << static_cast<uint32_t>(sensorDataSize)
271*a743e384SChau Ly << " presentReading 0x" << std::setw(8)
272*a743e384SChau Ly << static_cast<uint32_t>(presentReading) << std::dec;
273*a743e384SChau Ly description += strStream.str();
274*a743e384SChau Ly
275*a743e384SChau Ly sendJournalRedfish(description, logLevel);
276*a743e384SChau Ly break;
277*a743e384SChau Ly }
278*a743e384SChau Ly return PLDM_SUCCESS;
279*a743e384SChau Ly }
280*a743e384SChau Ly
processStateSensorEvent(pldm_tid_t tid,uint16_t sensorId,const uint8_t * sensorData,size_t sensorDataLength)281*a743e384SChau Ly int OemEventManager::processStateSensorEvent(pldm_tid_t tid, uint16_t sensorId,
282*a743e384SChau Ly const uint8_t* sensorData,
283*a743e384SChau Ly size_t sensorDataLength)
284*a743e384SChau Ly {
285*a743e384SChau Ly uint8_t sensorOffset = 0;
286*a743e384SChau Ly uint8_t eventState = 0;
287*a743e384SChau Ly uint8_t previousEventState = 0;
288*a743e384SChau Ly
289*a743e384SChau Ly auto rc =
290*a743e384SChau Ly decode_state_sensor_data(sensorData, sensorDataLength, &sensorOffset,
291*a743e384SChau Ly &eventState, &previousEventState);
292*a743e384SChau Ly if (rc)
293*a743e384SChau Ly {
294*a743e384SChau Ly lg2::error(
295*a743e384SChau Ly "Failed to decode stateSensorState event for terminus ID {TID}, error {RC}",
296*a743e384SChau Ly "TID", tid, "RC", rc);
297*a743e384SChau Ly return rc;
298*a743e384SChau Ly }
299*a743e384SChau Ly
300*a743e384SChau Ly std::string description;
301*a743e384SChau Ly std::stringstream strStream;
302*a743e384SChau Ly log_level logLevel = log_level::OK;
303*a743e384SChau Ly
304*a743e384SChau Ly description += "SENSOR_EVENT : STATE_SENSOR_STATE: ";
305*a743e384SChau Ly description += prefixMsgStrCreation(tid, sensorId);
306*a743e384SChau Ly strStream << std::setfill('0') << std::hex << "sensorOffset 0x"
307*a743e384SChau Ly << std::setw(2) << static_cast<uint32_t>(sensorOffset)
308*a743e384SChau Ly << "eventState 0x" << std::setw(2)
309*a743e384SChau Ly << static_cast<uint32_t>(eventState) << " previousEventState 0x"
310*a743e384SChau Ly << std::setw(2) << static_cast<uint32_t>(previousEventState)
311*a743e384SChau Ly << std::dec;
312*a743e384SChau Ly description += strStream.str();
313*a743e384SChau Ly
314*a743e384SChau Ly sendJournalRedfish(description, logLevel);
315*a743e384SChau Ly
316*a743e384SChau Ly return PLDM_SUCCESS;
317*a743e384SChau Ly }
318*a743e384SChau Ly
processSensorOpStateEvent(pldm_tid_t tid,uint16_t sensorId,const uint8_t * sensorData,size_t sensorDataLength)319*a743e384SChau Ly int OemEventManager::processSensorOpStateEvent(
320*a743e384SChau Ly pldm_tid_t tid, uint16_t sensorId, const uint8_t* sensorData,
321*a743e384SChau Ly size_t sensorDataLength)
322*a743e384SChau Ly {
323*a743e384SChau Ly uint8_t present_op_state = 0;
324*a743e384SChau Ly uint8_t previous_op_state = 0;
325*a743e384SChau Ly
326*a743e384SChau Ly auto rc = decode_sensor_op_data(sensorData, sensorDataLength,
327*a743e384SChau Ly &present_op_state, &previous_op_state);
328*a743e384SChau Ly if (rc)
329*a743e384SChau Ly {
330*a743e384SChau Ly lg2::error(
331*a743e384SChau Ly "Failed to decode sensorOpState event for terminus ID {TID}, error {RC}",
332*a743e384SChau Ly "TID", tid, "RC", rc);
333*a743e384SChau Ly return rc;
334*a743e384SChau Ly }
335*a743e384SChau Ly
336*a743e384SChau Ly std::string description;
337*a743e384SChau Ly std::stringstream strStream;
338*a743e384SChau Ly log_level logLevel = log_level::OK;
339*a743e384SChau Ly
340*a743e384SChau Ly description += "SENSOR_EVENT : SENSOR_OP_STATE: ";
341*a743e384SChau Ly description += prefixMsgStrCreation(tid, sensorId);
342*a743e384SChau Ly strStream << std::setfill('0') << std::hex << "present_op_state 0x"
343*a743e384SChau Ly << std::setw(2) << static_cast<uint32_t>(present_op_state)
344*a743e384SChau Ly << "previous_op_state 0x" << std::setw(2)
345*a743e384SChau Ly << static_cast<uint32_t>(previous_op_state) << std::dec;
346*a743e384SChau Ly description += strStream.str();
347*a743e384SChau Ly
348*a743e384SChau Ly sendJournalRedfish(description, logLevel);
349*a743e384SChau Ly
350*a743e384SChau Ly return PLDM_SUCCESS;
351*a743e384SChau Ly }
352*a743e384SChau Ly
handleSensorEvent(const pldm_msg * request,size_t payloadLength,uint8_t,pldm_tid_t tid,size_t eventDataOffset)353*a743e384SChau Ly int OemEventManager::handleSensorEvent(
354*a743e384SChau Ly const pldm_msg* request, size_t payloadLength, uint8_t /* formatVersion */,
355*a743e384SChau Ly pldm_tid_t tid, size_t eventDataOffset)
356*a743e384SChau Ly {
357*a743e384SChau Ly /* This OEM event handler is only used for SoC terminus*/
358*a743e384SChau Ly if (!tidToSocketNameMap.contains(tid))
359*a743e384SChau Ly {
360*a743e384SChau Ly return PLDM_SUCCESS;
361*a743e384SChau Ly }
362*a743e384SChau Ly auto eventData =
363*a743e384SChau Ly reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
364*a743e384SChau Ly auto eventDataSize = payloadLength - eventDataOffset;
365*a743e384SChau Ly
366*a743e384SChau Ly uint16_t sensorId = 0;
367*a743e384SChau Ly uint8_t sensorEventClassType = 0;
368*a743e384SChau Ly size_t eventClassDataOffset = 0;
369*a743e384SChau Ly auto rc =
370*a743e384SChau Ly decode_sensor_event_data(eventData, eventDataSize, &sensorId,
371*a743e384SChau Ly &sensorEventClassType, &eventClassDataOffset);
372*a743e384SChau Ly if (rc)
373*a743e384SChau Ly {
374*a743e384SChau Ly lg2::error("Failed to decode sensor event data return code {RC}.", "RC",
375*a743e384SChau Ly rc);
376*a743e384SChau Ly return rc;
377*a743e384SChau Ly }
378*a743e384SChau Ly const uint8_t* sensorData = eventData + eventClassDataOffset;
379*a743e384SChau Ly size_t sensorDataLength = eventDataSize - eventClassDataOffset;
380*a743e384SChau Ly
381*a743e384SChau Ly switch (sensorEventClassType)
382*a743e384SChau Ly {
383*a743e384SChau Ly case PLDM_NUMERIC_SENSOR_STATE:
384*a743e384SChau Ly {
385*a743e384SChau Ly return processNumericSensorEvent(tid, sensorId, sensorData,
386*a743e384SChau Ly sensorDataLength);
387*a743e384SChau Ly }
388*a743e384SChau Ly case PLDM_STATE_SENSOR_STATE:
389*a743e384SChau Ly {
390*a743e384SChau Ly return processStateSensorEvent(tid, sensorId, sensorData,
391*a743e384SChau Ly sensorDataLength);
392*a743e384SChau Ly }
393*a743e384SChau Ly case PLDM_SENSOR_OP_STATE:
394*a743e384SChau Ly {
395*a743e384SChau Ly return processSensorOpStateEvent(tid, sensorId, sensorData,
396*a743e384SChau Ly sensorDataLength);
397*a743e384SChau Ly }
398*a743e384SChau Ly default:
399*a743e384SChau Ly std::string description;
400*a743e384SChau Ly std::stringstream strStream;
401*a743e384SChau Ly log_level logLevel = log_level::OK;
402*a743e384SChau Ly
403*a743e384SChau Ly description += "SENSOR_EVENT : Unsupported Sensor Class " +
404*a743e384SChau Ly std::to_string(sensorEventClassType) + ": ";
405*a743e384SChau Ly description += prefixMsgStrCreation(tid, sensorId);
406*a743e384SChau Ly strStream << std::setfill('0') << std::hex
407*a743e384SChau Ly << std::setw(sizeof(sensorData) * 2) << "Sensor data: ";
408*a743e384SChau Ly
409*a743e384SChau Ly auto dataPtr = sensorData;
410*a743e384SChau Ly for ([[maybe_unused]] const auto& i :
411*a743e384SChau Ly std::views::iota(0, (int)sensorDataLength))
412*a743e384SChau Ly {
413*a743e384SChau Ly strStream << "0x" << static_cast<uint32_t>(*dataPtr);
414*a743e384SChau Ly dataPtr += sizeof(sensorData);
415*a743e384SChau Ly }
416*a743e384SChau Ly
417*a743e384SChau Ly description += strStream.str();
418*a743e384SChau Ly
419*a743e384SChau Ly sendJournalRedfish(description, logLevel);
420*a743e384SChau Ly }
421*a743e384SChau Ly lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE",
422*a743e384SChau Ly sensorEventClassType);
423*a743e384SChau Ly return PLDM_ERROR;
424*a743e384SChau Ly }
425*a743e384SChau Ly
426*a743e384SChau Ly } // namespace oem_ampere
427*a743e384SChau Ly } // namespace pldm
428