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