xref: /openbmc/pldm/platform-mc/event_manager.cpp (revision 6dce7d119cbfe9cacb0dd618ccfdba9f60ef05bf)
177e6fe7aSGilbert Chen #include "event_manager.hpp"
277e6fe7aSGilbert Chen 
3f48015b3SDung Cao #include "libpldm/platform.h"
477e6fe7aSGilbert Chen #include "libpldm/utils.h"
577e6fe7aSGilbert Chen 
677e6fe7aSGilbert Chen #include "terminus_manager.hpp"
777e6fe7aSGilbert Chen 
877e6fe7aSGilbert Chen #include <phosphor-logging/lg2.hpp>
977e6fe7aSGilbert Chen #include <xyz/openbmc_project/Logging/Entry/server.hpp>
1077e6fe7aSGilbert Chen 
1177e6fe7aSGilbert Chen #include <cerrno>
1277e6fe7aSGilbert Chen #include <memory>
1377e6fe7aSGilbert Chen 
1477e6fe7aSGilbert Chen PHOSPHOR_LOG2_USING;
1577e6fe7aSGilbert Chen 
1677e6fe7aSGilbert Chen namespace pldm
1777e6fe7aSGilbert Chen {
1877e6fe7aSGilbert Chen namespace platform_mc
1977e6fe7aSGilbert Chen {
2077e6fe7aSGilbert Chen namespace fs = std::filesystem;
2177e6fe7aSGilbert Chen 
handlePlatformEvent(pldm_tid_t tid,uint16_t eventId,uint8_t eventClass,const uint8_t * eventData,size_t eventDataSize)2277e6fe7aSGilbert Chen int EventManager::handlePlatformEvent(
2377e6fe7aSGilbert Chen     pldm_tid_t tid, uint16_t eventId, uint8_t eventClass,
2477e6fe7aSGilbert Chen     const uint8_t* eventData, size_t eventDataSize)
2577e6fe7aSGilbert Chen {
26bd0277e4SThu Nguyen     /* Only handle the event of the discovered termini*/
27bd0277e4SThu Nguyen     if (!termini.contains(tid))
28bd0277e4SThu Nguyen     {
29bd0277e4SThu Nguyen         lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
30bd0277e4SThu Nguyen                    tid);
31bd0277e4SThu Nguyen         return PLDM_ERROR;
32bd0277e4SThu Nguyen     }
33bd0277e4SThu Nguyen 
3477e6fe7aSGilbert Chen     /* EventClass sensorEvent `Table 11 - PLDM Event Types` DSP0248 */
3577e6fe7aSGilbert Chen     if (eventClass == PLDM_SENSOR_EVENT)
3677e6fe7aSGilbert Chen     {
3777e6fe7aSGilbert Chen         uint16_t sensorId = 0;
3877e6fe7aSGilbert Chen         uint8_t sensorEventClassType = 0;
3977e6fe7aSGilbert Chen         size_t eventClassDataOffset = 0;
4077e6fe7aSGilbert Chen         auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
4177e6fe7aSGilbert Chen                                            &sensorEventClassType,
4277e6fe7aSGilbert Chen                                            &eventClassDataOffset);
4377e6fe7aSGilbert Chen         if (rc)
4477e6fe7aSGilbert Chen         {
4577e6fe7aSGilbert Chen             lg2::error(
4677e6fe7aSGilbert Chen                 "Failed to decode sensor event data from terminus ID {TID}, event class {CLASS}, event ID {EVENTID} with return code {RC}.",
4777e6fe7aSGilbert Chen                 "TID", tid, "CLASS", eventClass, "EVENTID", eventId, "RC", rc);
4877e6fe7aSGilbert Chen             return rc;
4977e6fe7aSGilbert Chen         }
5077e6fe7aSGilbert Chen         switch (sensorEventClassType)
5177e6fe7aSGilbert Chen         {
5277e6fe7aSGilbert Chen             case PLDM_NUMERIC_SENSOR_STATE:
5377e6fe7aSGilbert Chen             {
5477e6fe7aSGilbert Chen                 const uint8_t* sensorData = eventData + eventClassDataOffset;
5577e6fe7aSGilbert Chen                 size_t sensorDataLength = eventDataSize - eventClassDataOffset;
5677e6fe7aSGilbert Chen                 return processNumericSensorEvent(tid, sensorId, sensorData,
5777e6fe7aSGilbert Chen                                                  sensorDataLength);
5877e6fe7aSGilbert Chen             }
5977e6fe7aSGilbert Chen             case PLDM_STATE_SENSOR_STATE:
6077e6fe7aSGilbert Chen             case PLDM_SENSOR_OP_STATE:
6177e6fe7aSGilbert Chen             default:
6277e6fe7aSGilbert Chen                 lg2::info(
6377e6fe7aSGilbert Chen                     "Unsupported class type {CLASSTYPE} for the sensor event from terminus ID {TID} sensorId {SID}",
6477e6fe7aSGilbert Chen                     "CLASSTYPE", sensorEventClassType, "TID", tid, "SID",
6577e6fe7aSGilbert Chen                     sensorId);
6677e6fe7aSGilbert Chen                 return PLDM_ERROR;
6777e6fe7aSGilbert Chen         }
6877e6fe7aSGilbert Chen     }
6977e6fe7aSGilbert Chen 
709fc79128SThu Nguyen     /* EventClass CPEREvent as `Table 11 - PLDM Event Types` DSP0248 V1.3.0 */
719fc79128SThu Nguyen     if (eventClass == PLDM_CPER_EVENT)
729fc79128SThu Nguyen     {
739fc79128SThu Nguyen         return processCperEvent(tid, eventId, eventData, eventDataSize);
749fc79128SThu Nguyen     }
759fc79128SThu Nguyen 
76f48015b3SDung Cao     /* EventClass pldmMessagePollEvent `Table 11 - PLDM Event Types` DSP0248 */
77f48015b3SDung Cao     if (eventClass == PLDM_MESSAGE_POLL_EVENT)
78f48015b3SDung Cao     {
79f48015b3SDung Cao         lg2::info("Received pldmMessagePollEvent for terminus {TID}", "TID",
80f48015b3SDung Cao                   tid);
81f48015b3SDung Cao         pldm_message_poll_event poll_event{};
82f48015b3SDung Cao         auto rc = decode_pldm_message_poll_event_data(eventData, eventDataSize,
83f48015b3SDung Cao                                                       &poll_event);
84f48015b3SDung Cao         if (rc)
85f48015b3SDung Cao         {
86f48015b3SDung Cao             lg2::error(
87f48015b3SDung Cao                 "Failed to decode PldmMessagePollEvent event, error {RC} ",
88f48015b3SDung Cao                 "RC", rc);
89f48015b3SDung Cao             return rc;
90f48015b3SDung Cao         }
91f48015b3SDung Cao 
92f48015b3SDung Cao         auto it = termini.find(tid);
93f48015b3SDung Cao         if (it != termini.end())
94f48015b3SDung Cao         {
95f48015b3SDung Cao             auto& terminus = it->second; // Reference for clarity
96f48015b3SDung Cao             terminus->pollEvent = true;
97f48015b3SDung Cao             terminus->pollEventId = poll_event.event_id;
98f48015b3SDung Cao             terminus->pollDataTransferHandle = poll_event.data_transfer_handle;
99f48015b3SDung Cao         }
100f48015b3SDung Cao 
101f48015b3SDung Cao         return PLDM_SUCCESS;
102f48015b3SDung Cao     }
103f48015b3SDung Cao 
10477e6fe7aSGilbert Chen     lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE", eventClass);
10577e6fe7aSGilbert Chen 
10677e6fe7aSGilbert Chen     return PLDM_ERROR;
10777e6fe7aSGilbert Chen }
10877e6fe7aSGilbert Chen 
processNumericSensorEvent(pldm_tid_t tid,uint16_t sensorId,const uint8_t * sensorData,size_t sensorDataLength)10977e6fe7aSGilbert Chen int EventManager::processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
11077e6fe7aSGilbert Chen                                             const uint8_t* sensorData,
11177e6fe7aSGilbert Chen                                             size_t sensorDataLength)
11277e6fe7aSGilbert Chen {
11377e6fe7aSGilbert Chen     uint8_t eventState = 0;
11477e6fe7aSGilbert Chen     uint8_t previousEventState = 0;
11577e6fe7aSGilbert Chen     uint8_t sensorDataSize = 0;
11677e6fe7aSGilbert Chen     uint32_t presentReading;
11777e6fe7aSGilbert Chen     auto rc = decode_numeric_sensor_data(
11877e6fe7aSGilbert Chen         sensorData, sensorDataLength, &eventState, &previousEventState,
11977e6fe7aSGilbert Chen         &sensorDataSize, &presentReading);
12077e6fe7aSGilbert Chen     if (rc)
12177e6fe7aSGilbert Chen     {
12277e6fe7aSGilbert Chen         lg2::error(
12377e6fe7aSGilbert Chen             "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ",
12477e6fe7aSGilbert Chen             "TID", tid, "RC", rc);
12577e6fe7aSGilbert Chen         return rc;
12677e6fe7aSGilbert Chen     }
12777e6fe7aSGilbert Chen 
12877e6fe7aSGilbert Chen     double value = static_cast<double>(presentReading);
12977e6fe7aSGilbert Chen     lg2::error(
13077e6fe7aSGilbert Chen         "processNumericSensorEvent tid {TID}, sensorID {SID} value {VAL} previousState {PSTATE} eventState {ESTATE}",
13177e6fe7aSGilbert Chen         "TID", tid, "SID", sensorId, "VAL", value, "PSTATE", previousEventState,
13277e6fe7aSGilbert Chen         "ESTATE", eventState);
13377e6fe7aSGilbert Chen 
13477e6fe7aSGilbert Chen     if (!termini.contains(tid) || !termini[tid])
13577e6fe7aSGilbert Chen     {
13677e6fe7aSGilbert Chen         lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
13777e6fe7aSGilbert Chen                    tid);
13877e6fe7aSGilbert Chen         return PLDM_ERROR;
13977e6fe7aSGilbert Chen     }
14077e6fe7aSGilbert Chen 
14177e6fe7aSGilbert Chen     auto& terminus = termini[tid];
14277e6fe7aSGilbert Chen 
14377e6fe7aSGilbert Chen     auto sensor = terminus->getSensorObject(sensorId);
14477e6fe7aSGilbert Chen     if (!sensor)
14577e6fe7aSGilbert Chen     {
14677e6fe7aSGilbert Chen         lg2::error(
14777e6fe7aSGilbert Chen             "Terminus ID {TID} has no sensor object with sensor ID {SID}.",
14877e6fe7aSGilbert Chen             "TID", tid, "SID", sensorId);
14977e6fe7aSGilbert Chen         return PLDM_ERROR;
15077e6fe7aSGilbert Chen     }
15177e6fe7aSGilbert Chen 
15277e6fe7aSGilbert Chen     switch (previousEventState)
15377e6fe7aSGilbert Chen     {
15477e6fe7aSGilbert Chen         case PLDM_SENSOR_UNKNOWN:
15577e6fe7aSGilbert Chen         case PLDM_SENSOR_NORMAL:
15677e6fe7aSGilbert Chen         {
15777e6fe7aSGilbert Chen             switch (eventState)
15877e6fe7aSGilbert Chen             {
15977e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERFATAL:
16077e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERCRITICAL:
16177e6fe7aSGilbert Chen                 {
16277e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
16377e6fe7aSGilbert Chen                                                   pldm::utils::Direction::HIGH,
16477e6fe7aSGilbert Chen                                                   value, true, true);
16577e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
16677e6fe7aSGilbert Chen                         pldm::utils::Level::CRITICAL,
16777e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, true, true);
16877e6fe7aSGilbert Chen                 }
16977e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERWARNING:
17077e6fe7aSGilbert Chen                 {
17177e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
17277e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
17377e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, true, true);
17477e6fe7aSGilbert Chen                 }
17577e6fe7aSGilbert Chen                 case PLDM_SENSOR_NORMAL:
17677e6fe7aSGilbert Chen                     break;
17777e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERWARNING:
17877e6fe7aSGilbert Chen                 {
17977e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
18077e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
18177e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, true, true);
18277e6fe7aSGilbert Chen                 }
18377e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERCRITICAL:
18477e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERFATAL:
18577e6fe7aSGilbert Chen                 {
18677e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
18777e6fe7aSGilbert Chen                                                   pldm::utils::Direction::LOW,
18877e6fe7aSGilbert Chen                                                   value, true, true);
18977e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
19077e6fe7aSGilbert Chen                         pldm::utils::Level::CRITICAL,
19177e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, true, true);
19277e6fe7aSGilbert Chen                 }
19377e6fe7aSGilbert Chen                 default:
19477e6fe7aSGilbert Chen                     break;
19577e6fe7aSGilbert Chen             }
19677e6fe7aSGilbert Chen             break;
19777e6fe7aSGilbert Chen         }
19877e6fe7aSGilbert Chen         case PLDM_SENSOR_LOWERWARNING:
19977e6fe7aSGilbert Chen         {
20077e6fe7aSGilbert Chen             switch (eventState)
20177e6fe7aSGilbert Chen             {
20277e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERFATAL:
20377e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERCRITICAL:
20477e6fe7aSGilbert Chen                     break;
20577e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERWARNING:
20677e6fe7aSGilbert Chen                 {
20777e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
20877e6fe7aSGilbert Chen                                                   pldm::utils::Direction::LOW,
20977e6fe7aSGilbert Chen                                                   value, false, false);
21077e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
21177e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
21277e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, true, true);
21377e6fe7aSGilbert Chen                 }
21477e6fe7aSGilbert Chen                 case PLDM_SENSOR_NORMAL:
21577e6fe7aSGilbert Chen                 {
21677e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
21777e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
21877e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, false, false);
21977e6fe7aSGilbert Chen                 }
22077e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERWARNING:
22177e6fe7aSGilbert Chen                     break;
22277e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERCRITICAL:
22377e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERFATAL:
22477e6fe7aSGilbert Chen                 {
22577e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
22677e6fe7aSGilbert Chen                         pldm::utils::Level::CRITICAL,
22777e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, true, true);
22877e6fe7aSGilbert Chen                 }
22977e6fe7aSGilbert Chen                 default:
23077e6fe7aSGilbert Chen                     break;
23177e6fe7aSGilbert Chen             }
23277e6fe7aSGilbert Chen             break;
23377e6fe7aSGilbert Chen         }
23477e6fe7aSGilbert Chen         case PLDM_SENSOR_LOWERCRITICAL:
23577e6fe7aSGilbert Chen         case PLDM_SENSOR_LOWERFATAL:
23677e6fe7aSGilbert Chen         {
23777e6fe7aSGilbert Chen             switch (eventState)
23877e6fe7aSGilbert Chen             {
23977e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERFATAL:
24077e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERCRITICAL:
24177e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERWARNING:
24277e6fe7aSGilbert Chen                     break;
24377e6fe7aSGilbert Chen                 case PLDM_SENSOR_NORMAL:
24477e6fe7aSGilbert Chen                 {
24577e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
24677e6fe7aSGilbert Chen                                                   pldm::utils::Direction::LOW,
24777e6fe7aSGilbert Chen                                                   value, false, false);
24877e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
24977e6fe7aSGilbert Chen                                                   pldm::utils::Direction::LOW,
25077e6fe7aSGilbert Chen                                                   value, true, true);
25177e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
25277e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
25377e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, false, false);
25477e6fe7aSGilbert Chen                 }
25577e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERWARNING:
25677e6fe7aSGilbert Chen                 {
25777e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
25877e6fe7aSGilbert Chen                                                   pldm::utils::Direction::LOW,
25977e6fe7aSGilbert Chen                                                   value, false, false);
26077e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
26177e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
26277e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, true, true);
26377e6fe7aSGilbert Chen                 }
26477e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERCRITICAL:
26577e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERFATAL:
26677e6fe7aSGilbert Chen                 default:
26777e6fe7aSGilbert Chen                     break;
26877e6fe7aSGilbert Chen             }
26977e6fe7aSGilbert Chen             break;
27077e6fe7aSGilbert Chen         }
27177e6fe7aSGilbert Chen         case PLDM_SENSOR_UPPERFATAL:
27277e6fe7aSGilbert Chen         case PLDM_SENSOR_UPPERCRITICAL:
27377e6fe7aSGilbert Chen         {
27477e6fe7aSGilbert Chen             switch (eventState)
27577e6fe7aSGilbert Chen             {
27677e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERFATAL:
27777e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERCRITICAL:
27877e6fe7aSGilbert Chen                     break;
27977e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERWARNING:
28077e6fe7aSGilbert Chen                 {
28177e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
28277e6fe7aSGilbert Chen                                                   pldm::utils::Direction::HIGH,
28377e6fe7aSGilbert Chen                                                   value, false, false);
28477e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
28577e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
28677e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, true, true);
28777e6fe7aSGilbert Chen                 }
28877e6fe7aSGilbert Chen                 case PLDM_SENSOR_NORMAL:
28977e6fe7aSGilbert Chen                 {
29077e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL,
29177e6fe7aSGilbert Chen                                                   pldm::utils::Direction::HIGH,
29277e6fe7aSGilbert Chen                                                   value, false, false);
29377e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
29477e6fe7aSGilbert Chen                                                   pldm::utils::Direction::HIGH,
29577e6fe7aSGilbert Chen                                                   value, true, true);
29677e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
29777e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
29877e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, false, false);
29977e6fe7aSGilbert Chen                 }
30077e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERWARNING:
30177e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERCRITICAL:
30277e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERFATAL:
30377e6fe7aSGilbert Chen                 default:
30477e6fe7aSGilbert Chen                     break;
30577e6fe7aSGilbert Chen             }
30677e6fe7aSGilbert Chen             break;
30777e6fe7aSGilbert Chen         }
30877e6fe7aSGilbert Chen         case PLDM_SENSOR_UPPERWARNING:
30977e6fe7aSGilbert Chen         {
31077e6fe7aSGilbert Chen             switch (eventState)
31177e6fe7aSGilbert Chen             {
31277e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERFATAL:
31377e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERCRITICAL:
31477e6fe7aSGilbert Chen                 {
31577e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
31677e6fe7aSGilbert Chen                         pldm::utils::Level::CRITICAL,
31777e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, true, true);
31877e6fe7aSGilbert Chen                 }
31977e6fe7aSGilbert Chen                 case PLDM_SENSOR_UPPERWARNING:
32077e6fe7aSGilbert Chen                     break;
32177e6fe7aSGilbert Chen                 case PLDM_SENSOR_NORMAL:
32277e6fe7aSGilbert Chen                 {
32377e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
32477e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
32577e6fe7aSGilbert Chen                         pldm::utils::Direction::HIGH, value, false, false);
32677e6fe7aSGilbert Chen                 }
32777e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERWARNING:
32877e6fe7aSGilbert Chen                 {
32977e6fe7aSGilbert Chen                     sensor->triggerThresholdEvent(pldm::utils::Level::WARNING,
33077e6fe7aSGilbert Chen                                                   pldm::utils::Direction::HIGH,
33177e6fe7aSGilbert Chen                                                   value, false, false);
33277e6fe7aSGilbert Chen                     return sensor->triggerThresholdEvent(
33377e6fe7aSGilbert Chen                         pldm::utils::Level::WARNING,
33477e6fe7aSGilbert Chen                         pldm::utils::Direction::LOW, value, true, true);
33577e6fe7aSGilbert Chen                 }
33677e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERCRITICAL:
33777e6fe7aSGilbert Chen                 case PLDM_SENSOR_LOWERFATAL:
33877e6fe7aSGilbert Chen                 default:
33977e6fe7aSGilbert Chen                     break;
34077e6fe7aSGilbert Chen             }
34177e6fe7aSGilbert Chen             break;
34277e6fe7aSGilbert Chen         }
34377e6fe7aSGilbert Chen         default:
34477e6fe7aSGilbert Chen             break;
34577e6fe7aSGilbert Chen     }
34677e6fe7aSGilbert Chen 
34777e6fe7aSGilbert Chen     return PLDM_SUCCESS;
34877e6fe7aSGilbert Chen }
34977e6fe7aSGilbert Chen 
processCperEvent(pldm_tid_t tid,uint16_t eventId,const uint8_t * eventData,const size_t eventDataSize)3509fc79128SThu Nguyen int EventManager::processCperEvent(pldm_tid_t tid, uint16_t eventId,
3519fc79128SThu Nguyen                                    const uint8_t* eventData,
3529fc79128SThu Nguyen                                    const size_t eventDataSize)
3539fc79128SThu Nguyen {
3549fc79128SThu Nguyen     if (eventDataSize < PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH)
3559fc79128SThu Nguyen     {
3569fc79128SThu Nguyen         lg2::error(
3579fc79128SThu Nguyen             "Error : Invalid CPER Event data length for eventId {EVENTID}.",
3589fc79128SThu Nguyen             "EVENTID", eventId);
3599fc79128SThu Nguyen         return PLDM_ERROR;
3609fc79128SThu Nguyen     }
3619fc79128SThu Nguyen     const size_t cperEventDataSize =
3629fc79128SThu Nguyen         eventDataSize - PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH;
3639fc79128SThu Nguyen     const size_t msgDataLen =
3649fc79128SThu Nguyen         sizeof(pldm_platform_cper_event) + cperEventDataSize;
3659fc79128SThu Nguyen     std::string terminusName = "";
3669fc79128SThu Nguyen     auto msgData = std::make_unique<unsigned char[]>(msgDataLen);
3679fc79128SThu Nguyen     auto cperEvent = new (msgData.get()) pldm_platform_cper_event;
3689fc79128SThu Nguyen 
3699fc79128SThu Nguyen     auto rc = decode_pldm_platform_cper_event(eventData, eventDataSize,
3709fc79128SThu Nguyen                                               cperEvent, msgDataLen);
3719fc79128SThu Nguyen 
3729fc79128SThu Nguyen     if (rc)
3739fc79128SThu Nguyen     {
3749fc79128SThu Nguyen         lg2::error(
3759fc79128SThu Nguyen             "Failed to decode CPER event for eventId {EVENTID} of terminus ID {TID} error {RC}.",
3769fc79128SThu Nguyen             "EVENTID", eventId, "TID", tid, "RC", rc);
3779fc79128SThu Nguyen         return rc;
3789fc79128SThu Nguyen     }
3799fc79128SThu Nguyen 
380dd6f36cbSThu Nguyen     if (termini.contains(tid) && termini[tid])
3819fc79128SThu Nguyen     {
3829fc79128SThu Nguyen         auto tmp = termini[tid]->getTerminusName();
3839fc79128SThu Nguyen         if (tmp && !tmp.value().empty())
3849fc79128SThu Nguyen         {
3859fc79128SThu Nguyen             terminusName = static_cast<std::string>(tmp.value());
3869fc79128SThu Nguyen         }
3879fc79128SThu Nguyen     }
388bd0277e4SThu Nguyen     else
389bd0277e4SThu Nguyen     {
390bd0277e4SThu Nguyen         lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
391bd0277e4SThu Nguyen                    tid);
392bd0277e4SThu Nguyen         return PLDM_ERROR;
393bd0277e4SThu Nguyen     }
3949fc79128SThu Nguyen 
3959fc79128SThu Nguyen     // Save event data to file
3969fc79128SThu Nguyen     std::filesystem::path dirName{"/var/cper"};
3979fc79128SThu Nguyen     if (!std::filesystem::exists(dirName))
3989fc79128SThu Nguyen     {
3999fc79128SThu Nguyen         try
4009fc79128SThu Nguyen         {
4019fc79128SThu Nguyen             std::filesystem::create_directory(dirName);
4029fc79128SThu Nguyen         }
4039fc79128SThu Nguyen         catch (const std::filesystem::filesystem_error& e)
4049fc79128SThu Nguyen         {
4059fc79128SThu Nguyen             lg2::error("Failed to create /var/cper directory: {ERROR}", "ERROR",
4069fc79128SThu Nguyen                        e);
4079fc79128SThu Nguyen             return PLDM_ERROR;
4089fc79128SThu Nguyen         }
4099fc79128SThu Nguyen     }
4109fc79128SThu Nguyen 
4119fc79128SThu Nguyen     std::string fileName{dirName.string() + "/cper-XXXXXX"};
4129fc79128SThu Nguyen     auto fd = mkstemp(fileName.data());
4139fc79128SThu Nguyen     if (fd < 0)
4149fc79128SThu Nguyen     {
4159fc79128SThu Nguyen         lg2::error("Failed to generate temp file, error {ERRORNO}", "ERRORNO",
4169fc79128SThu Nguyen                    std::strerror(errno));
4179fc79128SThu Nguyen         return PLDM_ERROR;
4189fc79128SThu Nguyen     }
4199fc79128SThu Nguyen     close(fd);
4209fc79128SThu Nguyen 
4219fc79128SThu Nguyen     std::ofstream ofs;
4229fc79128SThu Nguyen     ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit |
4239fc79128SThu Nguyen                    std::ofstream::eofbit);
4249fc79128SThu Nguyen 
4259fc79128SThu Nguyen     try
4269fc79128SThu Nguyen     {
4279fc79128SThu Nguyen         ofs.open(fileName);
4289fc79128SThu Nguyen         ofs.write(reinterpret_cast<const char*>(
4299fc79128SThu Nguyen                       pldm_platform_cper_event_event_data(cperEvent)),
4309fc79128SThu Nguyen                   cperEvent->event_data_length);
4319fc79128SThu Nguyen         if (cperEvent->format_type == PLDM_PLATFORM_CPER_EVENT_WITH_HEADER)
4329fc79128SThu Nguyen         {
4339fc79128SThu Nguyen             rc = createCperDumpEntry("CPER", fileName, terminusName);
4349fc79128SThu Nguyen         }
4359fc79128SThu Nguyen         else
4369fc79128SThu Nguyen         {
4379fc79128SThu Nguyen             rc = createCperDumpEntry("CPERSection", fileName, terminusName);
4389fc79128SThu Nguyen         }
4399fc79128SThu Nguyen         ofs.close();
4409fc79128SThu Nguyen     }
4419fc79128SThu Nguyen     catch (const std::ofstream::failure& e)
4429fc79128SThu Nguyen     {
4439fc79128SThu Nguyen         lg2::error("Failed to save CPER to '{FILENAME}', error - {ERROR}.",
4449fc79128SThu Nguyen                    "FILENAME", fileName, "ERROR", e);
4459fc79128SThu Nguyen         return PLDM_ERROR;
4469fc79128SThu Nguyen     }
4479fc79128SThu Nguyen     return rc;
4489fc79128SThu Nguyen }
4499fc79128SThu Nguyen 
createCperDumpEntry(const std::string & dataType,const std::string & dataPath,const std::string & typeName)4509fc79128SThu Nguyen int EventManager::createCperDumpEntry(const std::string& dataType,
4519fc79128SThu Nguyen                                       const std::string& dataPath,
4529fc79128SThu Nguyen                                       const std::string& typeName)
4539fc79128SThu Nguyen {
4549fc79128SThu Nguyen     auto createDump =
4559fc79128SThu Nguyen         [](std::map<std::string, std::variant<std::string, uint64_t>>&
4569fc79128SThu Nguyen                addData) {
4579fc79128SThu Nguyen             static constexpr auto dumpObjPath =
4589fc79128SThu Nguyen                 "/xyz/openbmc_project/dump/faultlog";
4599fc79128SThu Nguyen             static constexpr auto dumpInterface =
4609fc79128SThu Nguyen                 "xyz.openbmc_project.Dump.Create";
4619fc79128SThu Nguyen             auto& bus = pldm::utils::DBusHandler::getBus();
4629fc79128SThu Nguyen 
4639fc79128SThu Nguyen             try
4649fc79128SThu Nguyen             {
4659fc79128SThu Nguyen                 auto service = pldm::utils::DBusHandler().getService(
4669fc79128SThu Nguyen                     dumpObjPath, dumpInterface);
4679fc79128SThu Nguyen                 auto method = bus.new_method_call(service.c_str(), dumpObjPath,
4689fc79128SThu Nguyen                                                   dumpInterface, "CreateDump");
4699fc79128SThu Nguyen                 method.append(addData);
4709fc79128SThu Nguyen                 bus.call_noreply(method);
4719fc79128SThu Nguyen             }
4729fc79128SThu Nguyen             catch (const std::exception& e)
4739fc79128SThu Nguyen             {
4749fc79128SThu Nguyen                 lg2::error(
4759fc79128SThu Nguyen                     "Failed to create D-Bus Dump entry, error - {ERROR}.",
4769fc79128SThu Nguyen                     "ERROR", e);
4779fc79128SThu Nguyen             }
4789fc79128SThu Nguyen         };
4799fc79128SThu Nguyen 
4809fc79128SThu Nguyen     std::map<std::string, std::variant<std::string, uint64_t>> addData;
4819fc79128SThu Nguyen     addData["Type"] = dataType;
4829fc79128SThu Nguyen     addData["PrimaryLogId"] = dataPath;
4839fc79128SThu Nguyen     addData["AdditionalTypeName"] = typeName;
4849fc79128SThu Nguyen     createDump(addData);
4859fc79128SThu Nguyen     return PLDM_SUCCESS;
4869fc79128SThu Nguyen }
4879fc79128SThu Nguyen 
getNextPartParameters(uint16_t eventId,std::vector<uint8_t> eventMessage,uint8_t transferFlag,uint32_t eventDataIntegrityChecksum,uint32_t nextDataTransferHandle,uint8_t * transferOperationFlag,uint32_t * dataTransferHandle,uint32_t * eventIdToAcknowledge)488f48015b3SDung Cao int EventManager::getNextPartParameters(
489f48015b3SDung Cao     uint16_t eventId, std::vector<uint8_t> eventMessage, uint8_t transferFlag,
490f48015b3SDung Cao     uint32_t eventDataIntegrityChecksum, uint32_t nextDataTransferHandle,
491f48015b3SDung Cao     uint8_t* transferOperationFlag, uint32_t* dataTransferHandle,
492f48015b3SDung Cao     uint32_t* eventIdToAcknowledge)
493f48015b3SDung Cao {
494f48015b3SDung Cao     if (transferFlag != PLDM_PLATFORM_TRANSFER_START_AND_END &&
495f48015b3SDung Cao         transferFlag != PLDM_PLATFORM_TRANSFER_END)
496f48015b3SDung Cao     {
497f48015b3SDung Cao         *transferOperationFlag = PLDM_GET_NEXTPART;
498f48015b3SDung Cao         *dataTransferHandle = nextDataTransferHandle;
499f48015b3SDung Cao         *eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_FRAGMENT;
500f48015b3SDung Cao         return PLDM_SUCCESS;
501f48015b3SDung Cao     }
502f48015b3SDung Cao 
503f48015b3SDung Cao     if (transferFlag == PLDM_PLATFORM_TRANSFER_END)
504f48015b3SDung Cao     {
505f48015b3SDung Cao         if (eventDataIntegrityChecksum !=
506f48015b3SDung Cao             crc32(eventMessage.data(), eventMessage.size()))
507f48015b3SDung Cao         {
508f48015b3SDung Cao             lg2::error("pollForPlatformEventMessage invalid checksum.");
509f48015b3SDung Cao             return PLDM_ERROR_INVALID_DATA;
510f48015b3SDung Cao         }
511f48015b3SDung Cao     }
512f48015b3SDung Cao 
513f48015b3SDung Cao     /* End of one event. Set request transfer flag to ACK */
514f48015b3SDung Cao     *transferOperationFlag = PLDM_ACKNOWLEDGEMENT_ONLY;
515f48015b3SDung Cao     *dataTransferHandle = 0;
516f48015b3SDung Cao     *eventIdToAcknowledge = eventId;
517f48015b3SDung Cao 
518f48015b3SDung Cao     return PLDM_SUCCESS;
519f48015b3SDung Cao }
520f48015b3SDung Cao 
callPolledEventHandlers(pldm_tid_t tid,uint8_t eventClass,uint16_t eventId,std::vector<uint8_t> & eventMessage)521*6dce7d11SThu Nguyen void EventManager::callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass,
522*6dce7d11SThu Nguyen                                            uint16_t eventId,
523*6dce7d11SThu Nguyen                                            std::vector<uint8_t>& eventMessage)
524*6dce7d11SThu Nguyen {
525*6dce7d11SThu Nguyen     try
526*6dce7d11SThu Nguyen     {
527*6dce7d11SThu Nguyen         const auto& handlers = eventHandlers.at(eventClass);
528*6dce7d11SThu Nguyen         for (const auto& handler : handlers)
529*6dce7d11SThu Nguyen         {
530*6dce7d11SThu Nguyen             auto rc =
531*6dce7d11SThu Nguyen                 handler(tid, eventId, eventMessage.data(), eventMessage.size());
532*6dce7d11SThu Nguyen             if (rc != PLDM_SUCCESS)
533*6dce7d11SThu Nguyen             {
534*6dce7d11SThu Nguyen                 lg2::error(
535*6dce7d11SThu Nguyen                     "Failed to handle platform event msg for terminus {TID}, event {EVENTID} return {RET}",
536*6dce7d11SThu Nguyen                     "TID", tid, "EVENTID", eventId, "RET", rc);
537*6dce7d11SThu Nguyen             }
538*6dce7d11SThu Nguyen         }
539*6dce7d11SThu Nguyen     }
540*6dce7d11SThu Nguyen     catch (const std::out_of_range& e)
541*6dce7d11SThu Nguyen     {
542*6dce7d11SThu Nguyen         lg2::error(
543*6dce7d11SThu Nguyen             "Failed to handle platform event msg for terminus {TID}, event {EVENTID} error - {ERROR}",
544*6dce7d11SThu Nguyen             "TID", tid, "EVENTID", eventId, "ERROR", e);
545*6dce7d11SThu Nguyen     }
546*6dce7d11SThu Nguyen }
547*6dce7d11SThu Nguyen 
pollForPlatformEventTask(pldm_tid_t tid,uint32_t pollDataTransferHandle)548f48015b3SDung Cao exec::task<int> EventManager::pollForPlatformEventTask(
549f48015b3SDung Cao     pldm_tid_t tid, uint32_t pollDataTransferHandle)
550f48015b3SDung Cao {
551f48015b3SDung Cao     uint8_t rc = 0;
552f48015b3SDung Cao     // Set once, doesn't need resetting
553f48015b3SDung Cao     uint8_t transferOperationFlag = PLDM_GET_FIRSTPART;
554f48015b3SDung Cao     uint32_t dataTransferHandle = pollDataTransferHandle;
555f48015b3SDung Cao     uint32_t eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NULL;
556f48015b3SDung Cao     uint8_t formatVersion = 0x1; // Constant, no need to reset
557f48015b3SDung Cao     uint16_t eventId = PLDM_PLATFORM_EVENT_ID_ACK;
558f48015b3SDung Cao     uint16_t polledEventId = PLDM_PLATFORM_EVENT_ID_NONE;
559f48015b3SDung Cao     pldm_tid_t polledEventTid = 0;
560f48015b3SDung Cao     uint8_t polledEventClass = 0;
561f48015b3SDung Cao 
562f48015b3SDung Cao     std::vector<uint8_t> eventMessage{};
563f48015b3SDung Cao 
564f48015b3SDung Cao     // Reset and mark terminus as available
565f48015b3SDung Cao     updateAvailableState(tid, true);
566f48015b3SDung Cao 
567f48015b3SDung Cao     while (eventId != PLDM_PLATFORM_EVENT_ID_NONE)
568f48015b3SDung Cao     {
569f48015b3SDung Cao         uint8_t completionCode = 0;
570f48015b3SDung Cao         pldm_tid_t eventTid = PLDM_PLATFORM_EVENT_ID_NONE;
571f48015b3SDung Cao         eventId = PLDM_PLATFORM_EVENT_ID_NONE;
572f48015b3SDung Cao         uint32_t nextDataTransferHandle = 0;
573f48015b3SDung Cao         uint8_t transferFlag = 0;
574f48015b3SDung Cao         uint8_t eventClass = 0;
575f48015b3SDung Cao         uint32_t eventDataSize = 0;
576f48015b3SDung Cao         uint8_t* eventData = nullptr;
577f48015b3SDung Cao         uint32_t eventDataIntegrityChecksum = 0;
578f48015b3SDung Cao 
579f48015b3SDung Cao         /* Stop event polling */
580f48015b3SDung Cao         if (!getAvailableState(tid))
581f48015b3SDung Cao         {
582f48015b3SDung Cao             lg2::info(
583f48015b3SDung Cao                 "Terminus ID {TID} is not available for PLDM request from {NOW}.",
584f48015b3SDung Cao                 "TID", tid, "NOW", pldm::utils::getCurrentSystemTime());
585f48015b3SDung Cao             co_await stdexec::just_stopped();
586f48015b3SDung Cao         }
587f48015b3SDung Cao 
588f48015b3SDung Cao         rc = co_await pollForPlatformEventMessage(
589f48015b3SDung Cao             tid, formatVersion, transferOperationFlag, dataTransferHandle,
590f48015b3SDung Cao             eventIdToAcknowledge, completionCode, eventTid, eventId,
591f48015b3SDung Cao             nextDataTransferHandle, transferFlag, eventClass, eventDataSize,
592f48015b3SDung Cao             eventData, eventDataIntegrityChecksum);
593f48015b3SDung Cao         if (rc || completionCode != PLDM_SUCCESS)
594f48015b3SDung Cao         {
595f48015b3SDung Cao             lg2::error(
596f48015b3SDung Cao                 "Failed to pollForPlatformEventMessage for terminus {TID}, event {EVENTID}, error {RC}, complete code {CC}",
597f48015b3SDung Cao                 "TID", tid, "EVENTID", eventId, "RC", rc, "CC", completionCode);
598f48015b3SDung Cao             co_return rc;
599f48015b3SDung Cao         }
600f48015b3SDung Cao 
601f48015b3SDung Cao         if (eventDataSize > 0)
602f48015b3SDung Cao         {
603f48015b3SDung Cao             eventMessage.insert(eventMessage.end(), eventData,
604f48015b3SDung Cao                                 eventData + eventDataSize);
605f48015b3SDung Cao         }
606f48015b3SDung Cao 
607f48015b3SDung Cao         if (transferOperationFlag == PLDM_ACKNOWLEDGEMENT_ONLY)
608f48015b3SDung Cao         {
609f48015b3SDung Cao             /* Handle the polled event after finish ACK it */
610f48015b3SDung Cao             if (eventHandlers.contains(polledEventClass))
611f48015b3SDung Cao             {
612*6dce7d11SThu Nguyen                 callPolledEventHandlers(polledEventTid, polledEventClass,
613*6dce7d11SThu Nguyen                                         polledEventId, eventMessage);
614f48015b3SDung Cao             }
615f48015b3SDung Cao             eventMessage.clear();
616f48015b3SDung Cao 
617f48015b3SDung Cao             if (eventId == PLDM_PLATFORM_EVENT_ID_ACK)
618f48015b3SDung Cao             {
619f48015b3SDung Cao                 transferOperationFlag = PLDM_GET_FIRSTPART;
620f48015b3SDung Cao                 dataTransferHandle = 0;
621f48015b3SDung Cao                 eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NULL;
622f48015b3SDung Cao             }
623f48015b3SDung Cao         }
624f48015b3SDung Cao         else
625f48015b3SDung Cao         {
626f48015b3SDung Cao             auto ret = getNextPartParameters(
627f48015b3SDung Cao                 eventId, eventMessage, transferFlag, eventDataIntegrityChecksum,
628f48015b3SDung Cao                 nextDataTransferHandle, &transferOperationFlag,
629f48015b3SDung Cao                 &dataTransferHandle, &eventIdToAcknowledge);
630f48015b3SDung Cao             if (ret)
631f48015b3SDung Cao             {
632f48015b3SDung Cao                 lg2::error(
633f48015b3SDung Cao                     "Failed to process data of pollForPlatformEventMessage for terminus {TID}, event {EVENTID} return {RET}",
634f48015b3SDung Cao                     "TID", tid, "EVENTID", eventId, "RET", ret);
635f48015b3SDung Cao                 co_return PLDM_ERROR_INVALID_DATA;
636f48015b3SDung Cao             }
637f48015b3SDung Cao 
638f48015b3SDung Cao             /* Store the polled event INFO to handle after ACK */
639f48015b3SDung Cao             if ((transferFlag == PLDM_PLATFORM_TRANSFER_START_AND_END) ||
640f48015b3SDung Cao                 (transferFlag == PLDM_PLATFORM_TRANSFER_END))
641f48015b3SDung Cao             {
642f48015b3SDung Cao                 polledEventTid = eventTid;
643f48015b3SDung Cao                 polledEventId = eventId;
644f48015b3SDung Cao                 polledEventClass = eventClass;
645f48015b3SDung Cao             }
646f48015b3SDung Cao         }
647f48015b3SDung Cao     }
648f48015b3SDung Cao 
649f48015b3SDung Cao     co_return PLDM_SUCCESS;
650f48015b3SDung Cao }
651f48015b3SDung Cao 
pollForPlatformEventMessage(pldm_tid_t tid,uint8_t formatVersion,uint8_t transferOperationFlag,uint32_t dataTransferHandle,uint16_t eventIdToAcknowledge,uint8_t & completionCode,uint8_t & eventTid,uint16_t & eventId,uint32_t & nextDataTransferHandle,uint8_t & transferFlag,uint8_t & eventClass,uint32_t & eventDataSize,uint8_t * & eventData,uint32_t & eventDataIntegrityChecksum)652f48015b3SDung Cao exec::task<int> EventManager::pollForPlatformEventMessage(
653f48015b3SDung Cao     pldm_tid_t tid, uint8_t formatVersion, uint8_t transferOperationFlag,
654f48015b3SDung Cao     uint32_t dataTransferHandle, uint16_t eventIdToAcknowledge,
655f48015b3SDung Cao     uint8_t& completionCode, uint8_t& eventTid, uint16_t& eventId,
656f48015b3SDung Cao     uint32_t& nextDataTransferHandle, uint8_t& transferFlag,
657f48015b3SDung Cao     uint8_t& eventClass, uint32_t& eventDataSize, uint8_t*& eventData,
658f48015b3SDung Cao     uint32_t& eventDataIntegrityChecksum)
659f48015b3SDung Cao {
660f48015b3SDung Cao     Request request(
661f48015b3SDung Cao         sizeof(pldm_msg_hdr) + PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
662f48015b3SDung Cao     auto requestMsg = new (request.data()) pldm_msg;
663f48015b3SDung Cao     auto rc = encode_poll_for_platform_event_message_req(
664f48015b3SDung Cao         0, formatVersion, transferOperationFlag, dataTransferHandle,
665f48015b3SDung Cao         eventIdToAcknowledge, requestMsg, request.size());
666f48015b3SDung Cao     if (rc)
667f48015b3SDung Cao     {
668f48015b3SDung Cao         lg2::error(
669f48015b3SDung Cao             "Failed to encode request PollForPlatformEventMessage for terminus ID {TID}, error {RC} ",
670f48015b3SDung Cao             "TID", tid, "RC", rc);
671f48015b3SDung Cao         co_return rc;
672f48015b3SDung Cao     }
673f48015b3SDung Cao 
674f48015b3SDung Cao     /* Stop event polling */
675f48015b3SDung Cao     if (!getAvailableState(tid))
676f48015b3SDung Cao     {
677f48015b3SDung Cao         lg2::info(
678f48015b3SDung Cao             "Terminus ID {TID} is not available for PLDM request from {NOW}.",
679f48015b3SDung Cao             "TID", tid, "NOW", pldm::utils::getCurrentSystemTime());
680f48015b3SDung Cao         co_await stdexec::just_stopped();
681f48015b3SDung Cao     }
682f48015b3SDung Cao 
683f48015b3SDung Cao     const pldm_msg* responseMsg = nullptr;
684f48015b3SDung Cao     size_t responseLen = 0;
685f48015b3SDung Cao     rc = co_await terminusManager.sendRecvPldmMsg(tid, request, &responseMsg,
686f48015b3SDung Cao                                                   &responseLen);
687f48015b3SDung Cao     if (rc)
688f48015b3SDung Cao     {
689f48015b3SDung Cao         lg2::error(
690f48015b3SDung Cao             "Failed to send PollForPlatformEventMessage message for terminus {TID}, error {RC}",
691f48015b3SDung Cao             "TID", tid, "RC", rc);
692f48015b3SDung Cao         co_return rc;
693f48015b3SDung Cao     }
694f48015b3SDung Cao 
695f48015b3SDung Cao     rc = decode_poll_for_platform_event_message_resp(
696f48015b3SDung Cao         responseMsg, responseLen, &completionCode, &eventTid, &eventId,
697f48015b3SDung Cao         &nextDataTransferHandle, &transferFlag, &eventClass, &eventDataSize,
698f48015b3SDung Cao         (void**)&eventData, &eventDataIntegrityChecksum);
699f48015b3SDung Cao     if (rc)
700f48015b3SDung Cao     {
701f48015b3SDung Cao         lg2::error(
702f48015b3SDung Cao             "Failed to decode response PollForPlatformEventMessage for terminus ID {TID}, error {RC} ",
703f48015b3SDung Cao             "TID", tid, "RC", rc);
704f48015b3SDung Cao         co_return rc;
705f48015b3SDung Cao     }
706f48015b3SDung Cao     if (completionCode != PLDM_SUCCESS)
707f48015b3SDung Cao     {
708f48015b3SDung Cao         lg2::error(
709f48015b3SDung Cao             "Error : PollForPlatformEventMessage for terminus ID {TID}, complete code {CC}.",
710f48015b3SDung Cao             "TID", tid, "CC", completionCode);
711f48015b3SDung Cao         co_return rc;
712f48015b3SDung Cao     }
713f48015b3SDung Cao 
714f48015b3SDung Cao     co_return completionCode;
715f48015b3SDung Cao }
716f48015b3SDung Cao 
71777e6fe7aSGilbert Chen } // namespace platform_mc
71877e6fe7aSGilbert Chen } // namespace pldm
719