1 #include "oem_ibm_handler.hpp"
2 
3 #include "file_io_type_lid.hpp"
4 #include "libpldmresponder/file_io.hpp"
5 #include "libpldmresponder/pdr_utils.hpp"
6 
7 #include <libpldm/entity.h>
8 #include <libpldm/entity_oem_ibm.h>
9 
10 #include <phosphor-logging/lg2.hpp>
11 
12 PHOSPHOR_LOG2_USING;
13 
14 using namespace pldm::pdr;
15 using namespace pldm::utils;
16 
17 namespace pldm
18 {
19 namespace responder
20 {
21 namespace oem_ibm_platform
22 {
23 int pldm::responder::oem_ibm_platform::Handler::
24     getOemStateSensorReadingsHandler(
25         EntityType entityType, EntityInstance entityInstance,
26         StateSetId stateSetId, CompositeCount compSensorCnt,
27         std::vector<get_sensor_state_field>& stateField)
28 {
29     int rc = PLDM_SUCCESS;
30     stateField.clear();
31 
32     for (size_t i = 0; i < compSensorCnt; i++)
33     {
34         uint8_t sensorOpState{};
35         if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
36             stateSetId == PLDM_OEM_IBM_BOOT_STATE)
37         {
38             sensorOpState = fetchBootSide(entityInstance, codeUpdate);
39         }
40         else
41         {
42             rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
43             break;
44         }
45         stateField.push_back({PLDM_SENSOR_ENABLED, PLDM_SENSOR_UNKNOWN,
46                               PLDM_SENSOR_UNKNOWN, sensorOpState});
47     }
48     return rc;
49 }
50 
51 int pldm::responder::oem_ibm_platform::Handler::
52     oemSetStateEffecterStatesHandler(
53         uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
54         uint8_t compEffecterCnt,
55         std::vector<set_effecter_state_field>& stateField,
56         uint16_t /*effecterId*/)
57 {
58     int rc = PLDM_SUCCESS;
59 
60     for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
61     {
62         if (stateField[currState].set_request == PLDM_REQUEST_SET)
63         {
64             if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
65                 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
66             {
67                 rc = setBootSide(entityInstance, currState, stateField,
68                                  codeUpdate);
69             }
70             else if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
71                      stateSetId == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
72             {
73                 if (stateField[currState].effecter_state ==
74                     uint8_t(CodeUpdateState::START))
75                 {
76                     codeUpdate->setCodeUpdateProgress(true);
77                     startUpdateEvent =
78                         std::make_unique<sdeventplus::source::Defer>(
79                             event,
80                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
81                                                       _processStartUpdate),
82                                       this, std::placeholders::_1));
83                 }
84                 else if (stateField[currState].effecter_state ==
85                          uint8_t(CodeUpdateState::END))
86                 {
87                     rc = PLDM_SUCCESS;
88                     assembleImageEvent = std::make_unique<
89                         sdeventplus::source::Defer>(
90                         event,
91                         std::bind(
92                             std::mem_fn(
93                                 &oem_ibm_platform::Handler::_processEndUpdate),
94                             this, std::placeholders::_1));
95 
96                     // sendCodeUpdateEvent(effecterId, END, START);
97                 }
98                 else if (stateField[currState].effecter_state ==
99                          uint8_t(CodeUpdateState::ABORT))
100                 {
101                     codeUpdate->setCodeUpdateProgress(false);
102                     codeUpdate->clearDirPath(LID_STAGING_DIR);
103                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
104                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
105                                          uint8_t(CodeUpdateState::ABORT),
106                                          uint8_t(CodeUpdateState::START));
107                     // sendCodeUpdateEvent(effecterId, ABORT, END);
108                 }
109                 else if (stateField[currState].effecter_state ==
110                          uint8_t(CodeUpdateState::ACCEPT))
111                 {
112                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
113                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
114                                          uint8_t(CodeUpdateState::ACCEPT),
115                                          uint8_t(CodeUpdateState::END));
116                     // TODO Set new Dbus property provided by code update app
117                     // sendCodeUpdateEvent(effecterId, ACCEPT, END);
118                 }
119                 else if (stateField[currState].effecter_state ==
120                          uint8_t(CodeUpdateState::REJECT))
121                 {
122                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
123                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
124                                          uint8_t(CodeUpdateState::REJECT),
125                                          uint8_t(CodeUpdateState::END));
126                     // TODO Set new Dbus property provided by code update app
127                     // sendCodeUpdateEvent(effecterId, REJECT, END);
128                 }
129             }
130             else if (entityType == PLDM_ENTITY_SYSTEM_CHASSIS &&
131                      stateSetId == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
132             {
133                 if (stateField[currState].effecter_state == POWER_CYCLE_HARD)
134                 {
135                     systemRebootEvent =
136                         std::make_unique<sdeventplus::source::Defer>(
137                             event,
138                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
139                                                       _processSystemReboot),
140                                       this, std::placeholders::_1));
141                 }
142             }
143             else
144             {
145                 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
146             }
147         }
148         if (rc != PLDM_SUCCESS)
149         {
150             break;
151         }
152     }
153     return rc;
154 }
155 
156 void buildAllCodeUpdateEffecterPDR(oem_ibm_platform::Handler* platformHandler,
157                                    uint16_t entityType, uint16_t entityInstance,
158                                    uint16_t stateSetID, pdr_utils::Repo& repo)
159 {
160     size_t pdrSize = 0;
161     pdrSize = sizeof(pldm_state_effecter_pdr) +
162               sizeof(state_effecter_possible_states);
163     std::vector<uint8_t> entry{};
164     entry.resize(pdrSize);
165     pldm_state_effecter_pdr* pdr =
166         reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
167     if (!pdr)
168     {
169         error("Failed to get record by PDR type, ERROR:{ERR_CODE}", "ERR_CODE",
170               lg2::hex,
171               static_cast<unsigned>(PLDM_PLATFORM_INVALID_EFFECTER_ID));
172         return;
173     }
174     pdr->hdr.record_handle = 0;
175     pdr->hdr.version = 1;
176     pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
177     pdr->hdr.record_change_num = 0;
178     pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
179     pdr->terminus_handle = TERMINUS_HANDLE;
180     pdr->effecter_id = platformHandler->getNextEffecterId();
181     pdr->entity_type = entityType;
182     pdr->entity_instance = entityInstance;
183     pdr->container_id = 1;
184     pdr->effecter_semantic_id = 0;
185     pdr->effecter_init = PLDM_NO_INIT;
186     pdr->has_description_pdr = false;
187     pdr->composite_effecter_count = 1;
188 
189     auto* possibleStatesPtr = pdr->possible_states;
190     auto possibleStates =
191         reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
192     possibleStates->state_set_id = stateSetID;
193     possibleStates->possible_states_size = 2;
194     auto state =
195         reinterpret_cast<state_effecter_possible_states*>(possibleStates);
196     if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
197         state->states[0].byte = 6;
198     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
199         state->states[0].byte = 126;
200     else if (stateSetID == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
201         state->states[0].byte = 2;
202     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
203     pdrEntry.data = entry.data();
204     pdrEntry.size = pdrSize;
205     repo.addRecord(pdrEntry);
206 }
207 
208 void buildAllCodeUpdateSensorPDR(oem_ibm_platform::Handler* platformHandler,
209                                  uint16_t entityType, uint16_t entityInstance,
210                                  uint16_t stateSetID, pdr_utils::Repo& repo)
211 {
212     size_t pdrSize = 0;
213     pdrSize = sizeof(pldm_state_sensor_pdr) +
214               sizeof(state_sensor_possible_states);
215     std::vector<uint8_t> entry{};
216     entry.resize(pdrSize);
217     pldm_state_sensor_pdr* pdr =
218         reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
219     if (!pdr)
220     {
221         error("Failed to get record by PDR type, ERROR:{ERR_CODE}", "ERR_CODE",
222               lg2::hex, static_cast<unsigned>(PLDM_PLATFORM_INVALID_SENSOR_ID));
223         return;
224     }
225     pdr->hdr.record_handle = 0;
226     pdr->hdr.version = 1;
227     pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
228     pdr->hdr.record_change_num = 0;
229     pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
230     pdr->terminus_handle = TERMINUS_HANDLE;
231     pdr->sensor_id = platformHandler->getNextSensorId();
232     pdr->entity_type = entityType;
233     pdr->entity_instance = entityInstance;
234     pdr->container_id = 1;
235     pdr->sensor_init = PLDM_NO_INIT;
236     pdr->sensor_auxiliary_names_pdr = false;
237     pdr->composite_sensor_count = 1;
238 
239     auto* possibleStatesPtr = pdr->possible_states;
240     auto possibleStates =
241         reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
242     possibleStates->state_set_id = stateSetID;
243     possibleStates->possible_states_size = 2;
244     auto state =
245         reinterpret_cast<state_sensor_possible_states*>(possibleStates);
246     if ((stateSetID == PLDM_OEM_IBM_BOOT_STATE) ||
247         (stateSetID == PLDM_OEM_IBM_VERIFICATION_STATE))
248         state->states[0].byte = 6;
249     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
250         state->states[0].byte = 126;
251     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
252     pdrEntry.data = entry.data();
253     pdrEntry.size = pdrSize;
254     repo.addRecord(pdrEntry);
255 }
256 
257 void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
258     pdr_utils::Repo& repo)
259 {
260     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
261                                   ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
262                                   repo);
263     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
264                                   ENTITY_INSTANCE_1, PLDM_OEM_IBM_BOOT_STATE,
265                                   repo);
266     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
267                                   ENTITY_INSTANCE_0,
268                                   PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
269     buildAllCodeUpdateEffecterPDR(this, PLDM_ENTITY_SYSTEM_CHASSIS,
270                                   ENTITY_INSTANCE_1,
271                                   PLDM_OEM_IBM_SYSTEM_POWER_STATE, repo);
272 
273     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
274                                 ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
275                                 repo);
276     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
277                                 ENTITY_INSTANCE_1, PLDM_OEM_IBM_BOOT_STATE,
278                                 repo);
279     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
280                                 ENTITY_INSTANCE_0,
281                                 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
282     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
283                                 ENTITY_INSTANCE_0,
284                                 PLDM_OEM_IBM_VERIFICATION_STATE, repo);
285     auto sensorId = findStateSensorId(
286         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
287         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_VERIFICATION_STATE);
288     codeUpdate->setMarkerLidSensor(sensorId);
289     sensorId = findStateSensorId(
290         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
291         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE);
292     codeUpdate->setFirmwareUpdateSensor(sensorId);
293 }
294 
295 void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
296     pldm::responder::platform::Handler* handler)
297 {
298     platformHandler = handler;
299 }
300 
301 int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
302     std::vector<uint8_t>& requestMsg, uint8_t instanceId)
303 {
304     if (requestMsg.size())
305     {
306         std::ostringstream tempStream;
307         for (int byte : requestMsg)
308         {
309             tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
310                        << " ";
311         }
312         std::cout << tempStream.str() << std::endl;
313     }
314     auto oemPlatformEventMessageResponseHandler =
315         [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
316         uint8_t completionCode{};
317         uint8_t status{};
318         auto rc = decode_platform_event_message_resp(response, respMsgLen,
319                                                      &completionCode, &status);
320         if (rc || completionCode)
321         {
322             error(
323                 "Failed to decode_platform_event_message_resp: for code update event rc={RC}, cc={CC}",
324                 "RC", rc, "CC", static_cast<unsigned>(completionCode));
325         }
326     };
327     auto rc = handler->registerRequest(
328         mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
329         std::move(requestMsg),
330         std::move(oemPlatformEventMessageResponseHandler));
331     if (rc)
332     {
333         error("Failed to send BIOS attribute change event message ");
334     }
335 
336     return rc;
337 }
338 
339 int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
340                    std::vector<uint8_t>& requestMsg, uint8_t instanceId)
341 {
342     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
343 
344     auto rc = encode_platform_event_message_req(
345         instanceId, 1 /*formatVersion*/, TERMINUS_ID /*tId*/, eventType,
346         eventDataVec.data(), eventDataVec.size(), request,
347         eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
348 
349     return rc;
350 }
351 
352 void pldm::responder::oem_ibm_platform::Handler::sendStateSensorEvent(
353     uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
354     uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
355 {
356     std::vector<uint8_t> sensorEventDataVec{};
357     size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
358     sensorEventDataVec.resize(sensorEventSize);
359     auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>(
360         sensorEventDataVec.data());
361     eventData->sensor_id = sensorId;
362     eventData->sensor_event_class_type = sensorEventClass;
363     auto eventClassStart = eventData->event_class;
364     auto eventClass =
365         reinterpret_cast<struct pldm_sensor_event_state_sensor_state*>(
366             eventClassStart);
367     eventClass->sensor_offset = sensorOffset;
368     eventClass->event_state = eventState;
369     eventClass->previous_event_state = prevEventState;
370     auto instanceId = instanceIdDb.next(mctp_eid);
371     std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
372                                     PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
373                                     sensorEventDataVec.size());
374     auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
375                              instanceId);
376     if (rc != PLDM_SUCCESS)
377     {
378         error("Failed to encode state sensor event, rc = {RC}", "RC", rc);
379         instanceIdDb.free(mctp_eid, instanceId);
380         return;
381     }
382     rc = sendEventToHost(requestMsg, instanceId);
383     if (rc != PLDM_SUCCESS)
384     {
385         error("Failed to send event to host: rc={RC}", "RC", rc);
386     }
387     return;
388 }
389 
390 void pldm::responder::oem_ibm_platform::Handler::_processEndUpdate(
391     sdeventplus::source::EventBase& /*source */)
392 {
393     assembleImageEvent.reset();
394     int retc = codeUpdate->assembleCodeUpdateImage();
395     if (retc != PLDM_SUCCESS)
396     {
397         codeUpdate->setCodeUpdateProgress(false);
398         auto sensorId = codeUpdate->getFirmwareUpdateSensor();
399         sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
400                              uint8_t(CodeUpdateState::FAIL),
401                              uint8_t(CodeUpdateState::START));
402     }
403 }
404 
405 void pldm::responder::oem_ibm_platform::Handler::_processStartUpdate(
406     sdeventplus::source::EventBase& /*source */)
407 {
408     codeUpdate->deleteImage();
409     CodeUpdateState state = CodeUpdateState::START;
410     auto rc = codeUpdate->setRequestedApplyTime();
411     if (rc != PLDM_SUCCESS)
412     {
413         error("setRequestedApplyTime failed");
414         state = CodeUpdateState::FAIL;
415     }
416     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
417     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0, uint8_t(state),
418                          uint8_t(CodeUpdateState::END));
419 }
420 
421 void pldm::responder::oem_ibm_platform::Handler::_processSystemReboot(
422     sdeventplus::source::EventBase& /*source */)
423 {
424     pldm::utils::PropertyValue value =
425         "xyz.openbmc_project.State.Chassis.Transition.Off";
426     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/state/chassis0",
427                                          "xyz.openbmc_project.State.Chassis",
428                                          "RequestedPowerTransition", "string"};
429     try
430     {
431         dBusIntf->setDbusProperty(dbusMapping, value);
432     }
433     catch (const std::exception& e)
434     {
435         error(
436             "Chassis State transition to Off failed, unable to set property RequestedPowerTransition ERROR={ERR_EXCEP}",
437             "ERR_EXCEP", e.what());
438     }
439 
440     using namespace sdbusplus::bus::match::rules;
441     chassisOffMatch = std::make_unique<sdbusplus::bus::match_t>(
442         pldm::utils::DBusHandler::getBus(),
443         propertiesChanged("/xyz/openbmc_project/state/chassis0",
444                           "xyz.openbmc_project.State.Chassis"),
445         [this](sdbusplus::message_t& msg) {
446         DbusChangedProps props{};
447         std::string intf;
448         msg.read(intf, props);
449         const auto itr = props.find("CurrentPowerState");
450         if (itr != props.end())
451         {
452             PropertyValue value = itr->second;
453             auto propVal = std::get<std::string>(value);
454             if (propVal == "xyz.openbmc_project.State.Chassis.PowerState.Off")
455             {
456                 pldm::utils::DBusMapping dbusMapping{
457                     "/xyz/openbmc_project/control/host0/"
458                     "power_restore_policy/one_time",
459                     "xyz.openbmc_project.Control.Power.RestorePolicy",
460                     "PowerRestorePolicy", "string"};
461                 value = "xyz.openbmc_project.Control.Power.RestorePolicy."
462                         "Policy.AlwaysOn";
463                 try
464                 {
465                     dBusIntf->setDbusProperty(dbusMapping, value);
466                 }
467                 catch (const std::exception& e)
468                 {
469                     error(
470                         "Setting one-time restore policy failed, unable to set property PowerRestorePolicy ERROR={ERR_EXCEP}",
471                         "ERR_EXCEP", e.what());
472                 }
473                 dbusMapping = pldm::utils::DBusMapping{
474                     "/xyz/openbmc_project/state/bmc0",
475                     "xyz.openbmc_project.State.BMC", "RequestedBMCTransition",
476                     "string"};
477                 value = "xyz.openbmc_project.State.BMC.Transition.Reboot";
478                 try
479                 {
480                     dBusIntf->setDbusProperty(dbusMapping, value);
481                 }
482                 catch (const std::exception& e)
483                 {
484                     error(
485                         "BMC state transition to reboot failed, unable to set property RequestedBMCTransition ERROR={ERR_EXCEP}",
486                         "ERR_EXCEP", e.what());
487                 }
488             }
489         }
490     });
491 }
492 
493 void pldm::responder::oem_ibm_platform::Handler::checkAndDisableWatchDog()
494 {
495     if (!hostOff && setEventReceiverCnt == SET_EVENT_RECEIVER_SENT)
496     {
497         disableWatchDogTimer();
498     }
499 
500     return;
501 }
502 
503 bool pldm::responder::oem_ibm_platform::Handler::watchDogRunning()
504 {
505     static constexpr auto watchDogObjectPath =
506         "/xyz/openbmc_project/watchdog/host0";
507     static constexpr auto watchDogEnablePropName = "Enabled";
508     static constexpr auto watchDogInterface =
509         "xyz.openbmc_project.State.Watchdog";
510     bool isWatchDogRunning = false;
511     try
512     {
513         isWatchDogRunning = pldm::utils::DBusHandler().getDbusProperty<bool>(
514             watchDogObjectPath, watchDogEnablePropName, watchDogInterface);
515     }
516     catch (const std::exception& e)
517     {
518         return false;
519     }
520     return isWatchDogRunning;
521 }
522 
523 void pldm::responder::oem_ibm_platform::Handler::resetWatchDogTimer()
524 {
525     static constexpr auto watchDogService = "xyz.openbmc_project.Watchdog";
526     static constexpr auto watchDogObjectPath =
527         "/xyz/openbmc_project/watchdog/host0";
528     static constexpr auto watchDogInterface =
529         "xyz.openbmc_project.State.Watchdog";
530     static constexpr auto watchDogResetPropName = "ResetTimeRemaining";
531 
532     bool wdStatus = watchDogRunning();
533     if (wdStatus == false)
534     {
535         return;
536     }
537     try
538     {
539         auto& bus = pldm::utils::DBusHandler::getBus();
540         auto resetMethod =
541             bus.new_method_call(watchDogService, watchDogObjectPath,
542                                 watchDogInterface, watchDogResetPropName);
543         resetMethod.append(true);
544         bus.call_noreply(resetMethod, dbusTimeout);
545     }
546     catch (const std::exception& e)
547     {
548         error("Failed To reset watchdog timer ERROR={ERR_EXCEP}", "ERR_EXCEP",
549               e.what());
550         return;
551     }
552 }
553 
554 void pldm::responder::oem_ibm_platform::Handler::disableWatchDogTimer()
555 {
556     setEventReceiverCnt = 0;
557     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/watchdog/host0",
558                                          "xyz.openbmc_project.State.Watchdog",
559                                          "Enabled", "bool"};
560     bool wdStatus = watchDogRunning();
561 
562     if (!wdStatus)
563     {
564         return;
565     }
566     try
567     {
568         pldm::utils::DBusHandler().setDbusProperty(dbusMapping, false);
569     }
570     catch (const std::exception& e)
571     {
572         error("Failed To disable watchdog timer ERROR={ERR_EXCEP}", "ERR_EXCEP",
573               e.what());
574     }
575 }
576 int pldm::responder::oem_ibm_platform::Handler::checkBMCState()
577 {
578     try
579     {
580         pldm::utils::PropertyValue propertyValue =
581             pldm::utils::DBusHandler().getDbusPropertyVariant(
582                 "/xyz/openbmc_project/state/bmc0", "CurrentBMCState",
583                 "xyz.openbmc_project.State.BMC");
584 
585         if (std::get<std::string>(propertyValue) ==
586             "xyz.openbmc_project.State.BMC.BMCState.NotReady")
587         {
588             error("GetPDR : PLDM stack is not ready for PDR exchange");
589             return PLDM_ERROR_NOT_READY;
590         }
591     }
592     catch (const std::exception& e)
593     {
594         error("Error getting the current BMC state");
595         return PLDM_ERROR;
596     }
597     return PLDM_SUCCESS;
598 }
599 
600 const pldm_pdr_record*
601     pldm::responder::oem_ibm_platform::Handler::fetchLastBMCRecord(
602         const pldm_pdr* repo)
603 {
604     return pldm_pdr_find_last_in_range(repo, BMC_PDR_START_RANGE,
605                                        BMC_PDR_END_RANGE);
606 }
607 
608 bool pldm::responder::oem_ibm_platform::Handler::checkRecordHandleInRange(
609     const uint32_t& record_handle)
610 {
611     return record_handle >= HOST_PDR_START_RANGE &&
612            record_handle <= HOST_PDR_END_RANGE;
613 }
614 
615 } // namespace oem_ibm_platform
616 } // namespace responder
617 } // namespace pldm
618