blob: 4697b413cdfb4c96affe7579fc4f9879525e0910 [file] [log] [blame]
Gilbert Chen77e6fe72024-08-06 09:23:30 +00001#include "event_manager.hpp"
2
Gilbert Chen77e6fe72024-08-06 09:23:30 +00003#include "terminus_manager.hpp"
4
Manojkiran Edafe252792025-03-13 19:24:19 +05305#include <libpldm/platform.h>
6#include <libpldm/utils.h>
7
Gilbert Chen77e6fe72024-08-06 09:23:30 +00008#include <phosphor-logging/lg2.hpp>
9#include <xyz/openbmc_project/Logging/Entry/server.hpp>
10
11#include <cerrno>
12#include <memory>
13
14PHOSPHOR_LOG2_USING;
15
16namespace pldm
17{
18namespace platform_mc
19{
20namespace fs = std::filesystem;
21
22int EventManager::handlePlatformEvent(
23 pldm_tid_t tid, uint16_t eventId, uint8_t eventClass,
24 const uint8_t* eventData, size_t eventDataSize)
25{
Thu Nguyenbd0277e2024-10-11 10:11:09 +000026 /* Only handle the event of the discovered termini*/
27 if (!termini.contains(tid))
28 {
29 lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
30 tid);
31 return PLDM_ERROR;
32 }
33
Gilbert Chen77e6fe72024-08-06 09:23:30 +000034 /* EventClass sensorEvent `Table 11 - PLDM Event Types` DSP0248 */
35 if (eventClass == PLDM_SENSOR_EVENT)
36 {
37 uint16_t sensorId = 0;
38 uint8_t sensorEventClassType = 0;
39 size_t eventClassDataOffset = 0;
40 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
41 &sensorEventClassType,
42 &eventClassDataOffset);
43 if (rc)
44 {
45 lg2::error(
46 "Failed to decode sensor event data from terminus ID {TID}, event class {CLASS}, event ID {EVENTID} with return code {RC}.",
47 "TID", tid, "CLASS", eventClass, "EVENTID", eventId, "RC", rc);
48 return rc;
49 }
50 switch (sensorEventClassType)
51 {
52 case PLDM_NUMERIC_SENSOR_STATE:
53 {
54 const uint8_t* sensorData = eventData + eventClassDataOffset;
55 size_t sensorDataLength = eventDataSize - eventClassDataOffset;
56 return processNumericSensorEvent(tid, sensorId, sensorData,
57 sensorDataLength);
58 }
59 case PLDM_STATE_SENSOR_STATE:
60 case PLDM_SENSOR_OP_STATE:
61 default:
62 lg2::info(
63 "Unsupported class type {CLASSTYPE} for the sensor event from terminus ID {TID} sensorId {SID}",
64 "CLASSTYPE", sensorEventClassType, "TID", tid, "SID",
65 sensorId);
66 return PLDM_ERROR;
67 }
68 }
69
Thu Nguyen9fc79122024-09-10 10:15:01 +000070 /* EventClass CPEREvent as `Table 11 - PLDM Event Types` DSP0248 V1.3.0 */
71 if (eventClass == PLDM_CPER_EVENT)
72 {
73 return processCperEvent(tid, eventId, eventData, eventDataSize);
74 }
75
Dung Caof48015b2023-11-21 04:38:29 +000076 /* EventClass pldmMessagePollEvent `Table 11 - PLDM Event Types` DSP0248 */
77 if (eventClass == PLDM_MESSAGE_POLL_EVENT)
78 {
79 lg2::info("Received pldmMessagePollEvent for terminus {TID}", "TID",
80 tid);
81 pldm_message_poll_event poll_event{};
82 auto rc = decode_pldm_message_poll_event_data(eventData, eventDataSize,
83 &poll_event);
84 if (rc)
85 {
86 lg2::error(
87 "Failed to decode PldmMessagePollEvent event, error {RC} ",
88 "RC", rc);
89 return rc;
90 }
91
92 auto it = termini.find(tid);
93 if (it != termini.end())
94 {
95 auto& terminus = it->second; // Reference for clarity
96 terminus->pollEvent = true;
97 terminus->pollEventId = poll_event.event_id;
98 terminus->pollDataTransferHandle = poll_event.data_transfer_handle;
99 }
100
101 return PLDM_SUCCESS;
102 }
103
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000104 lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE", eventClass);
105
106 return PLDM_ERROR;
107}
108
Amithash Prasad378e3f72025-05-01 15:34:05 -0700109int triggerNumericSensorThresholdEvent(NumericSensorThresholdHandler handler,
110 uint8_t previousEventState,
111 uint8_t nextEventState, double value)
112{
113 static const std::map<
114 uint8_t, std::tuple<pldm::utils::Level, pldm::utils::Direction>>
115 sensorEventMap = {
116 {PLDM_SENSOR_UPPERFATAL,
117 {pldm::utils::Level::HARDSHUTDOWN, pldm::utils::Direction::HIGH}},
118 {PLDM_SENSOR_UPPERCRITICAL,
119 {pldm::utils::Level::CRITICAL, pldm::utils::Direction::HIGH}},
120 {PLDM_SENSOR_UPPERWARNING,
121 {pldm::utils::Level::WARNING, pldm::utils::Direction::HIGH}},
122 {PLDM_SENSOR_LOWERWARNING,
123 {pldm::utils::Level::WARNING, pldm::utils::Direction::LOW}},
124 {PLDM_SENSOR_LOWERCRITICAL,
125 {pldm::utils::Level::CRITICAL, pldm::utils::Direction::LOW}},
126 {PLDM_SENSOR_LOWERFATAL,
127 {pldm::utils::Level::HARDSHUTDOWN, pldm::utils::Direction::LOW}},
128 };
129 static const std::array<uint8_t, 7> stateOrder = {
130 PLDM_SENSOR_LOWERFATAL, PLDM_SENSOR_LOWERCRITICAL,
131 PLDM_SENSOR_LOWERWARNING, PLDM_SENSOR_NORMAL,
132 PLDM_SENSOR_UPPERWARNING, PLDM_SENSOR_UPPERCRITICAL,
133 PLDM_SENSOR_UPPERFATAL};
134 constexpr auto normalIt = stateOrder.begin() + 3;
135 const auto normalState = *normalIt;
136 auto prevIt =
137 std::find(stateOrder.begin(), stateOrder.end(), previousEventState);
138 if (prevIt == stateOrder.end())
139 {
140 lg2::error("Undefined previous threshold event state: {EVENT}", "EVENT",
141 previousEventState);
142 return PLDM_ERROR;
143 }
144 auto nextIt =
145 std::find(stateOrder.begin(), stateOrder.end(), nextEventState);
146 if (nextIt == stateOrder.end())
147 {
148 lg2::error("Undefined current threshold event state: {EVENT}", "EVENT",
149 nextEventState);
150 return PLDM_ERROR;
151 }
152 if (prevIt == nextIt)
153 {
154 // Nothing to do. Return success early
155 return PLDM_SUCCESS;
156 }
157
158 // This is a rare condition. But if we are going wildy across the thresholds
159 // crossing PLDM_SENSOR_NORMAL (Example going from PLDM_SENSOR_LOWERFATAL to
160 // PLDM_SENSOR_UPPERFATAL in one event, then split it up into two)
161 if ((prevIt < normalIt && nextIt > normalIt) ||
162 (prevIt > normalIt && nextIt < normalIt))
163 {
164 int rc = triggerNumericSensorThresholdEvent(handler, *prevIt,
165 normalState, value);
166 if (rc != PLDM_SUCCESS)
167 {
168 lg2::error("Error handling {PREV} to current for numeric sensor",
169 "PREV", int(*prevIt));
170 return rc;
171 }
172 return triggerNumericSensorThresholdEvent(handler, normalState, *nextIt,
173 value);
174 }
175 bool goingUp = prevIt < nextIt;
176 bool gettingBetter = (prevIt < nextIt && prevIt < normalIt) ||
177 (prevIt > nextIt && prevIt > normalIt);
178
179 for (auto currIt = prevIt; currIt != nextIt; goingUp ? ++currIt : --currIt)
180 {
181 if (currIt == normalIt)
182 {
183 continue;
184 }
185 const auto& event = sensorEventMap.at(*currIt);
186
187 if (gettingBetter)
188 {
189 if (currIt != prevIt)
190 {
191 // Just trigger an event in case it was missed before
192 // we deassert. The implementation of triggerThresholdEvent
193 // should just no-op if it is already triggered.
194 handler(std::get<0>(event), std::get<1>(event), value, true,
195 true);
196 }
197 handler(std::get<0>(event), std::get<1>(event), value, false,
198 false);
199 }
200 else
201 {
202 handler(std::get<0>(event), std::get<1>(event), value, true, true);
203 }
204 }
205 if (nextIt != normalIt)
206 {
207 const auto& event = sensorEventMap.at(*nextIt);
208 return handler(std::get<0>(event), std::get<1>(event), value, true,
209 true);
210 }
211 return PLDM_SUCCESS;
212}
213
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000214int EventManager::processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
215 const uint8_t* sensorData,
216 size_t sensorDataLength)
217{
218 uint8_t eventState = 0;
219 uint8_t previousEventState = 0;
220 uint8_t sensorDataSize = 0;
221 uint32_t presentReading;
222 auto rc = decode_numeric_sensor_data(
223 sensorData, sensorDataLength, &eventState, &previousEventState,
224 &sensorDataSize, &presentReading);
225 if (rc)
226 {
227 lg2::error(
228 "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ",
229 "TID", tid, "RC", rc);
230 return rc;
231 }
232
233 double value = static_cast<double>(presentReading);
234 lg2::error(
235 "processNumericSensorEvent tid {TID}, sensorID {SID} value {VAL} previousState {PSTATE} eventState {ESTATE}",
236 "TID", tid, "SID", sensorId, "VAL", value, "PSTATE", previousEventState,
237 "ESTATE", eventState);
238
239 if (!termini.contains(tid) || !termini[tid])
240 {
241 lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
242 tid);
243 return PLDM_ERROR;
244 }
245
246 auto& terminus = termini[tid];
247
248 auto sensor = terminus->getSensorObject(sensorId);
249 if (!sensor)
250 {
251 lg2::error(
252 "Terminus ID {TID} has no sensor object with sensor ID {SID}.",
253 "TID", tid, "SID", sensorId);
254 return PLDM_ERROR;
255 }
Amithash Prasad378e3f72025-05-01 15:34:05 -0700256 auto sensorHandler =
257 [&sensor](pldm::utils::Level level, pldm::utils::Direction direction,
258 double rawValue, bool newAlarm, bool assert) {
259 return sensor->triggerThresholdEvent(level, direction, rawValue,
260 newAlarm, assert);
261 };
262 rc = triggerNumericSensorThresholdEvent(sensorHandler, previousEventState,
263 eventState, value);
264 if (rc)
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000265 {
Amithash Prasad378e3f72025-05-01 15:34:05 -0700266 lg2::error(
267 "Terminus ID {TID} sensor {SID} threshold handling had errors",
268 "TID", tid, "SID", sensorId);
269 return rc;
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000270 }
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000271 return PLDM_SUCCESS;
272}
273
Thu Nguyen9fc79122024-09-10 10:15:01 +0000274int EventManager::processCperEvent(pldm_tid_t tid, uint16_t eventId,
275 const uint8_t* eventData,
276 const size_t eventDataSize)
277{
278 if (eventDataSize < PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH)
279 {
280 lg2::error(
281 "Error : Invalid CPER Event data length for eventId {EVENTID}.",
282 "EVENTID", eventId);
283 return PLDM_ERROR;
284 }
285 const size_t cperEventDataSize =
286 eventDataSize - PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH;
287 const size_t msgDataLen =
288 sizeof(pldm_platform_cper_event) + cperEventDataSize;
289 std::string terminusName = "";
290 auto msgData = std::make_unique<unsigned char[]>(msgDataLen);
291 auto cperEvent = new (msgData.get()) pldm_platform_cper_event;
292
293 auto rc = decode_pldm_platform_cper_event(eventData, eventDataSize,
294 cperEvent, msgDataLen);
295
296 if (rc)
297 {
298 lg2::error(
299 "Failed to decode CPER event for eventId {EVENTID} of terminus ID {TID} error {RC}.",
300 "EVENTID", eventId, "TID", tid, "RC", rc);
301 return rc;
302 }
303
Thu Nguyendd6f36c2024-10-22 14:23:24 +0000304 if (termini.contains(tid) && termini[tid])
Thu Nguyen9fc79122024-09-10 10:15:01 +0000305 {
306 auto tmp = termini[tid]->getTerminusName();
307 if (tmp && !tmp.value().empty())
308 {
309 terminusName = static_cast<std::string>(tmp.value());
310 }
311 }
Thu Nguyenbd0277e2024-10-11 10:11:09 +0000312 else
313 {
314 lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
315 tid);
316 return PLDM_ERROR;
317 }
Thu Nguyen9fc79122024-09-10 10:15:01 +0000318
319 // Save event data to file
320 std::filesystem::path dirName{"/var/cper"};
321 if (!std::filesystem::exists(dirName))
322 {
323 try
324 {
325 std::filesystem::create_directory(dirName);
326 }
327 catch (const std::filesystem::filesystem_error& e)
328 {
329 lg2::error("Failed to create /var/cper directory: {ERROR}", "ERROR",
330 e);
331 return PLDM_ERROR;
332 }
333 }
334
335 std::string fileName{dirName.string() + "/cper-XXXXXX"};
336 auto fd = mkstemp(fileName.data());
337 if (fd < 0)
338 {
339 lg2::error("Failed to generate temp file, error {ERRORNO}", "ERRORNO",
340 std::strerror(errno));
341 return PLDM_ERROR;
342 }
343 close(fd);
344
345 std::ofstream ofs;
346 ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit |
347 std::ofstream::eofbit);
348
349 try
350 {
351 ofs.open(fileName);
352 ofs.write(reinterpret_cast<const char*>(
353 pldm_platform_cper_event_event_data(cperEvent)),
354 cperEvent->event_data_length);
355 if (cperEvent->format_type == PLDM_PLATFORM_CPER_EVENT_WITH_HEADER)
356 {
357 rc = createCperDumpEntry("CPER", fileName, terminusName);
358 }
359 else
360 {
361 rc = createCperDumpEntry("CPERSection", fileName, terminusName);
362 }
363 ofs.close();
364 }
365 catch (const std::ofstream::failure& e)
366 {
367 lg2::error("Failed to save CPER to '{FILENAME}', error - {ERROR}.",
368 "FILENAME", fileName, "ERROR", e);
369 return PLDM_ERROR;
370 }
371 return rc;
372}
373
374int EventManager::createCperDumpEntry(const std::string& dataType,
375 const std::string& dataPath,
376 const std::string& typeName)
377{
378 auto createDump =
379 [](std::map<std::string, std::variant<std::string, uint64_t>>&
380 addData) {
381 static constexpr auto dumpObjPath =
382 "/xyz/openbmc_project/dump/faultlog";
383 static constexpr auto dumpInterface =
384 "xyz.openbmc_project.Dump.Create";
385 auto& bus = pldm::utils::DBusHandler::getBus();
386
387 try
388 {
389 auto service = pldm::utils::DBusHandler().getService(
390 dumpObjPath, dumpInterface);
391 auto method = bus.new_method_call(service.c_str(), dumpObjPath,
392 dumpInterface, "CreateDump");
393 method.append(addData);
394 bus.call_noreply(method);
395 }
396 catch (const std::exception& e)
397 {
398 lg2::error(
399 "Failed to create D-Bus Dump entry, error - {ERROR}.",
400 "ERROR", e);
401 }
402 };
403
404 std::map<std::string, std::variant<std::string, uint64_t>> addData;
405 addData["Type"] = dataType;
406 addData["PrimaryLogId"] = dataPath;
407 addData["AdditionalTypeName"] = typeName;
408 createDump(addData);
409 return PLDM_SUCCESS;
410}
411
Dung Caof48015b2023-11-21 04:38:29 +0000412int EventManager::getNextPartParameters(
413 uint16_t eventId, std::vector<uint8_t> eventMessage, uint8_t transferFlag,
414 uint32_t eventDataIntegrityChecksum, uint32_t nextDataTransferHandle,
415 uint8_t* transferOperationFlag, uint32_t* dataTransferHandle,
416 uint32_t* eventIdToAcknowledge)
417{
418 if (transferFlag != PLDM_PLATFORM_TRANSFER_START_AND_END &&
419 transferFlag != PLDM_PLATFORM_TRANSFER_END)
420 {
421 *transferOperationFlag = PLDM_GET_NEXTPART;
422 *dataTransferHandle = nextDataTransferHandle;
423 *eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_FRAGMENT;
424 return PLDM_SUCCESS;
425 }
426
427 if (transferFlag == PLDM_PLATFORM_TRANSFER_END)
428 {
429 if (eventDataIntegrityChecksum !=
Andrew Jeffery2cb36eb2025-04-05 21:35:48 +1030430 pldm_edac_crc32(eventMessage.data(), eventMessage.size()))
Dung Caof48015b2023-11-21 04:38:29 +0000431 {
432 lg2::error("pollForPlatformEventMessage invalid checksum.");
433 return PLDM_ERROR_INVALID_DATA;
434 }
435 }
436
437 /* End of one event. Set request transfer flag to ACK */
438 *transferOperationFlag = PLDM_ACKNOWLEDGEMENT_ONLY;
439 *dataTransferHandle = 0;
440 *eventIdToAcknowledge = eventId;
441
442 return PLDM_SUCCESS;
443}
444
Thu Nguyen6dce7d12024-11-19 00:18:22 +0000445void EventManager::callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass,
446 uint16_t eventId,
447 std::vector<uint8_t>& eventMessage)
448{
449 try
450 {
451 const auto& handlers = eventHandlers.at(eventClass);
452 for (const auto& handler : handlers)
453 {
454 auto rc =
455 handler(tid, eventId, eventMessage.data(), eventMessage.size());
456 if (rc != PLDM_SUCCESS)
457 {
458 lg2::error(
459 "Failed to handle platform event msg for terminus {TID}, event {EVENTID} return {RET}",
460 "TID", tid, "EVENTID", eventId, "RET", rc);
461 }
462 }
463 }
464 catch (const std::out_of_range& e)
465 {
466 lg2::error(
467 "Failed to handle platform event msg for terminus {TID}, event {EVENTID} error - {ERROR}",
468 "TID", tid, "EVENTID", eventId, "ERROR", e);
469 }
470}
471
Dung Caof48015b2023-11-21 04:38:29 +0000472exec::task<int> EventManager::pollForPlatformEventTask(
473 pldm_tid_t tid, uint32_t pollDataTransferHandle)
474{
475 uint8_t rc = 0;
476 // Set once, doesn't need resetting
477 uint8_t transferOperationFlag = PLDM_GET_FIRSTPART;
478 uint32_t dataTransferHandle = pollDataTransferHandle;
479 uint32_t eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NULL;
480 uint8_t formatVersion = 0x1; // Constant, no need to reset
481 uint16_t eventId = PLDM_PLATFORM_EVENT_ID_ACK;
482 uint16_t polledEventId = PLDM_PLATFORM_EVENT_ID_NONE;
483 pldm_tid_t polledEventTid = 0;
484 uint8_t polledEventClass = 0;
485
486 std::vector<uint8_t> eventMessage{};
487
488 // Reset and mark terminus as available
489 updateAvailableState(tid, true);
490
491 while (eventId != PLDM_PLATFORM_EVENT_ID_NONE)
492 {
493 uint8_t completionCode = 0;
494 pldm_tid_t eventTid = PLDM_PLATFORM_EVENT_ID_NONE;
495 eventId = PLDM_PLATFORM_EVENT_ID_NONE;
496 uint32_t nextDataTransferHandle = 0;
497 uint8_t transferFlag = 0;
498 uint8_t eventClass = 0;
499 uint32_t eventDataSize = 0;
500 uint8_t* eventData = nullptr;
501 uint32_t eventDataIntegrityChecksum = 0;
502
503 /* Stop event polling */
504 if (!getAvailableState(tid))
505 {
506 lg2::info(
507 "Terminus ID {TID} is not available for PLDM request from {NOW}.",
508 "TID", tid, "NOW", pldm::utils::getCurrentSystemTime());
509 co_await stdexec::just_stopped();
510 }
511
512 rc = co_await pollForPlatformEventMessage(
513 tid, formatVersion, transferOperationFlag, dataTransferHandle,
514 eventIdToAcknowledge, completionCode, eventTid, eventId,
515 nextDataTransferHandle, transferFlag, eventClass, eventDataSize,
516 eventData, eventDataIntegrityChecksum);
517 if (rc || completionCode != PLDM_SUCCESS)
518 {
519 lg2::error(
520 "Failed to pollForPlatformEventMessage for terminus {TID}, event {EVENTID}, error {RC}, complete code {CC}",
521 "TID", tid, "EVENTID", eventId, "RC", rc, "CC", completionCode);
522 co_return rc;
523 }
524
525 if (eventDataSize > 0)
526 {
527 eventMessage.insert(eventMessage.end(), eventData,
528 eventData + eventDataSize);
529 }
530
531 if (transferOperationFlag == PLDM_ACKNOWLEDGEMENT_ONLY)
532 {
533 /* Handle the polled event after finish ACK it */
534 if (eventHandlers.contains(polledEventClass))
535 {
Thu Nguyen6dce7d12024-11-19 00:18:22 +0000536 callPolledEventHandlers(polledEventTid, polledEventClass,
537 polledEventId, eventMessage);
Dung Caof48015b2023-11-21 04:38:29 +0000538 }
539 eventMessage.clear();
540
541 if (eventId == PLDM_PLATFORM_EVENT_ID_ACK)
542 {
543 transferOperationFlag = PLDM_GET_FIRSTPART;
544 dataTransferHandle = 0;
545 eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NULL;
546 }
547 }
548 else
549 {
550 auto ret = getNextPartParameters(
551 eventId, eventMessage, transferFlag, eventDataIntegrityChecksum,
552 nextDataTransferHandle, &transferOperationFlag,
553 &dataTransferHandle, &eventIdToAcknowledge);
554 if (ret)
555 {
556 lg2::error(
557 "Failed to process data of pollForPlatformEventMessage for terminus {TID}, event {EVENTID} return {RET}",
558 "TID", tid, "EVENTID", eventId, "RET", ret);
559 co_return PLDM_ERROR_INVALID_DATA;
560 }
561
562 /* Store the polled event INFO to handle after ACK */
563 if ((transferFlag == PLDM_PLATFORM_TRANSFER_START_AND_END) ||
564 (transferFlag == PLDM_PLATFORM_TRANSFER_END))
565 {
566 polledEventTid = eventTid;
567 polledEventId = eventId;
568 polledEventClass = eventClass;
569 }
570 }
571 }
572
573 co_return PLDM_SUCCESS;
574}
575
576exec::task<int> EventManager::pollForPlatformEventMessage(
577 pldm_tid_t tid, uint8_t formatVersion, uint8_t transferOperationFlag,
578 uint32_t dataTransferHandle, uint16_t eventIdToAcknowledge,
579 uint8_t& completionCode, uint8_t& eventTid, uint16_t& eventId,
580 uint32_t& nextDataTransferHandle, uint8_t& transferFlag,
581 uint8_t& eventClass, uint32_t& eventDataSize, uint8_t*& eventData,
582 uint32_t& eventDataIntegrityChecksum)
583{
584 Request request(
585 sizeof(pldm_msg_hdr) + PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
586 auto requestMsg = new (request.data()) pldm_msg;
587 auto rc = encode_poll_for_platform_event_message_req(
588 0, formatVersion, transferOperationFlag, dataTransferHandle,
589 eventIdToAcknowledge, requestMsg, request.size());
590 if (rc)
591 {
592 lg2::error(
593 "Failed to encode request PollForPlatformEventMessage for terminus ID {TID}, error {RC} ",
594 "TID", tid, "RC", rc);
595 co_return rc;
596 }
597
598 /* Stop event polling */
599 if (!getAvailableState(tid))
600 {
601 lg2::info(
602 "Terminus ID {TID} is not available for PLDM request from {NOW}.",
603 "TID", tid, "NOW", pldm::utils::getCurrentSystemTime());
604 co_await stdexec::just_stopped();
605 }
606
607 const pldm_msg* responseMsg = nullptr;
608 size_t responseLen = 0;
609 rc = co_await terminusManager.sendRecvPldmMsg(tid, request, &responseMsg,
610 &responseLen);
611 if (rc)
612 {
613 lg2::error(
614 "Failed to send PollForPlatformEventMessage message for terminus {TID}, error {RC}",
615 "TID", tid, "RC", rc);
616 co_return rc;
617 }
618
619 rc = decode_poll_for_platform_event_message_resp(
620 responseMsg, responseLen, &completionCode, &eventTid, &eventId,
621 &nextDataTransferHandle, &transferFlag, &eventClass, &eventDataSize,
622 (void**)&eventData, &eventDataIntegrityChecksum);
623 if (rc)
624 {
625 lg2::error(
626 "Failed to decode response PollForPlatformEventMessage for terminus ID {TID}, error {RC} ",
627 "TID", tid, "RC", rc);
628 co_return rc;
629 }
630 if (completionCode != PLDM_SUCCESS)
631 {
632 lg2::error(
633 "Error : PollForPlatformEventMessage for terminus ID {TID}, complete code {CC}.",
634 "TID", tid, "CC", completionCode);
635 co_return rc;
636 }
637
638 co_return completionCode;
639}
640
Gilbert Chen77e6fe72024-08-06 09:23:30 +0000641} // namespace platform_mc
642} // namespace pldm