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 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 = 316 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) { 317 uint8_t completionCode{}; 318 uint8_t status{}; 319 auto rc = decode_platform_event_message_resp(response, respMsgLen, 320 &completionCode, &status); 321 if (rc || completionCode) 322 { 323 error( 324 "Failed to decode platform event message response for code update event with response code '{RC}' and completion code '{CC}'", 325 "RC", rc, "CC", completionCode); 326 } 327 }; 328 auto rc = handler->registerRequest( 329 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE, 330 std::move(requestMsg), 331 std::move(oemPlatformEventMessageResponseHandler)); 332 if (rc) 333 { 334 error("Failed to send BIOS attribute change event message "); 335 } 336 337 return rc; 338 } 339 340 int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec, 341 std::vector<uint8_t>& requestMsg, uint8_t instanceId) 342 { 343 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 344 345 auto rc = encode_platform_event_message_req( 346 instanceId, 1 /*formatVersion*/, TERMINUS_ID /*tId*/, eventType, 347 eventDataVec.data(), eventDataVec.size(), request, 348 eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES); 349 350 return rc; 351 } 352 353 void pldm::responder::oem_ibm_platform::Handler::sendStateSensorEvent( 354 uint16_t sensorId, enum sensor_event_class_states sensorEventClass, 355 uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState) 356 { 357 std::vector<uint8_t> sensorEventDataVec{}; 358 size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1; 359 sensorEventDataVec.resize(sensorEventSize); 360 auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>( 361 sensorEventDataVec.data()); 362 eventData->sensor_id = sensorId; 363 eventData->sensor_event_class_type = sensorEventClass; 364 auto eventClassStart = eventData->event_class; 365 auto eventClass = 366 reinterpret_cast<struct pldm_sensor_event_state_sensor_state*>( 367 eventClassStart); 368 eventClass->sensor_offset = sensorOffset; 369 eventClass->event_state = eventState; 370 eventClass->previous_event_state = prevEventState; 371 auto instanceId = instanceIdDb.next(mctp_eid); 372 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 373 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + 374 sensorEventDataVec.size()); 375 auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg, 376 instanceId); 377 if (rc != PLDM_SUCCESS) 378 { 379 error("Failed to encode state sensor event with response code '{RC}'", 380 "RC", rc); 381 instanceIdDb.free(mctp_eid, instanceId); 382 return; 383 } 384 rc = sendEventToHost(requestMsg, instanceId); 385 if (rc != PLDM_SUCCESS) 386 { 387 error( 388 "Failed to send event to remote terminus with response code '{RC}'", 389 "RC", rc); 390 } 391 return; 392 } 393 394 void pldm::responder::oem_ibm_platform::Handler::_processEndUpdate( 395 sdeventplus::source::EventBase& /*source */) 396 { 397 assembleImageEvent.reset(); 398 int retc = codeUpdate->assembleCodeUpdateImage(); 399 if (retc != PLDM_SUCCESS) 400 { 401 codeUpdate->setCodeUpdateProgress(false); 402 auto sensorId = codeUpdate->getFirmwareUpdateSensor(); 403 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0, 404 uint8_t(CodeUpdateState::FAIL), 405 uint8_t(CodeUpdateState::START)); 406 } 407 } 408 409 void pldm::responder::oem_ibm_platform::Handler::_processStartUpdate( 410 sdeventplus::source::EventBase& /*source */) 411 { 412 codeUpdate->deleteImage(); 413 CodeUpdateState state = CodeUpdateState::START; 414 auto rc = codeUpdate->setRequestedApplyTime(); 415 if (rc != PLDM_SUCCESS) 416 { 417 error("setRequestedApplyTime failed"); 418 state = CodeUpdateState::FAIL; 419 } 420 auto sensorId = codeUpdate->getFirmwareUpdateSensor(); 421 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0, uint8_t(state), 422 uint8_t(CodeUpdateState::END)); 423 } 424 425 void pldm::responder::oem_ibm_platform::Handler::updateOemDbusPaths( 426 std::string& dbusPath) 427 { 428 std::string toFind("system1/chassis1/motherboard1"); 429 if (dbusPath.find(toFind) != std::string::npos) 430 { 431 size_t pos = dbusPath.find(toFind); 432 dbusPath.replace(pos, toFind.length(), "system/chassis/motherboard"); 433 } 434 toFind = "system1"; 435 if (dbusPath.find(toFind) != std::string::npos) 436 { 437 size_t pos = dbusPath.find(toFind); 438 dbusPath.replace(pos, toFind.length(), "system"); 439 } 440 /* below logic to replace path 'motherboard/socket/chassis' to 441 'motherboard/chassis' or 'motherboard/socket123/chassis' to 442 'motherboard/chassis' */ 443 toFind = "socket"; 444 size_t pos1 = dbusPath.find(toFind); 445 // while loop to detect multiple substring 'socket' in the path 446 while (pos1 != std::string::npos) 447 { 448 size_t pos2 = dbusPath.substr(pos1 + 1).find('/') + 1; 449 // Replacing starting from substring to next occurence of char '/' 450 dbusPath.replace(pos1, pos2 + 1, ""); 451 pos1 = dbusPath.find(toFind); 452 } 453 } 454 455 void pldm::responder::oem_ibm_platform::Handler::_processSystemReboot( 456 sdeventplus::source::EventBase& /*source */) 457 { 458 pldm::utils::PropertyValue value = 459 "xyz.openbmc_project.State.Chassis.Transition.Off"; 460 pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/state/chassis0", 461 "xyz.openbmc_project.State.Chassis", 462 "RequestedPowerTransition", "string"}; 463 try 464 { 465 dBusIntf->setDbusProperty(dbusMapping, value); 466 } 467 catch (const std::exception& e) 468 { 469 error( 470 "Failure in chassis State transition to Off, unable to set property RequestedPowerTransition, error - {ERROR}", 471 "ERROR", e); 472 } 473 474 using namespace sdbusplus::bus::match::rules; 475 chassisOffMatch = std::make_unique<sdbusplus::bus::match_t>( 476 pldm::utils::DBusHandler::getBus(), 477 propertiesChanged("/xyz/openbmc_project/state/chassis0", 478 "xyz.openbmc_project.State.Chassis"), 479 [this](sdbusplus::message_t& msg) { 480 DbusChangedProps props{}; 481 std::string intf; 482 msg.read(intf, props); 483 const auto itr = props.find("CurrentPowerState"); 484 if (itr != props.end()) 485 { 486 PropertyValue value = itr->second; 487 auto propVal = std::get<std::string>(value); 488 if (propVal == "xyz.openbmc_project.State.Chassis.PowerState.Off") 489 { 490 pldm::utils::DBusMapping dbusMapping{ 491 "/xyz/openbmc_project/control/host0/" 492 "power_restore_policy/one_time", 493 "xyz.openbmc_project.Control.Power.RestorePolicy", 494 "PowerRestorePolicy", "string"}; 495 value = "xyz.openbmc_project.Control.Power.RestorePolicy." 496 "Policy.AlwaysOn"; 497 try 498 { 499 dBusIntf->setDbusProperty(dbusMapping, value); 500 } 501 catch (const std::exception& e) 502 { 503 error( 504 "Failure in setting one-time restore policy, unable to set property PowerRestorePolicy, error - {ERROR}", 505 "ERROR", e); 506 } 507 dbusMapping = pldm::utils::DBusMapping{ 508 "/xyz/openbmc_project/state/bmc0", 509 "xyz.openbmc_project.State.BMC", "RequestedBMCTransition", 510 "string"}; 511 value = "xyz.openbmc_project.State.BMC.Transition.Reboot"; 512 try 513 { 514 dBusIntf->setDbusProperty(dbusMapping, value); 515 } 516 catch (const std::exception& e) 517 { 518 error( 519 "Failure in BMC state transition to reboot, unable to set property RequestedBMCTransition , error - {ERROR}", 520 "ERROR", e); 521 } 522 } 523 } 524 }); 525 } 526 527 void pldm::responder::oem_ibm_platform::Handler::checkAndDisableWatchDog() 528 { 529 if (!hostOff && setEventReceiverCnt == SET_EVENT_RECEIVER_SENT) 530 { 531 disableWatchDogTimer(); 532 } 533 534 return; 535 } 536 537 bool pldm::responder::oem_ibm_platform::Handler::watchDogRunning() 538 { 539 static constexpr auto watchDogObjectPath = 540 "/xyz/openbmc_project/watchdog/host0"; 541 static constexpr auto watchDogEnablePropName = "Enabled"; 542 static constexpr auto watchDogInterface = 543 "xyz.openbmc_project.State.Watchdog"; 544 bool isWatchDogRunning = false; 545 try 546 { 547 isWatchDogRunning = pldm::utils::DBusHandler().getDbusProperty<bool>( 548 watchDogObjectPath, watchDogEnablePropName, watchDogInterface); 549 } 550 catch (const std::exception&) 551 { 552 return false; 553 } 554 return isWatchDogRunning; 555 } 556 557 void pldm::responder::oem_ibm_platform::Handler::resetWatchDogTimer() 558 { 559 static constexpr auto watchDogService = "xyz.openbmc_project.Watchdog"; 560 static constexpr auto watchDogObjectPath = 561 "/xyz/openbmc_project/watchdog/host0"; 562 static constexpr auto watchDogInterface = 563 "xyz.openbmc_project.State.Watchdog"; 564 static constexpr auto watchDogResetPropName = "ResetTimeRemaining"; 565 566 bool wdStatus = watchDogRunning(); 567 if (wdStatus == false) 568 { 569 return; 570 } 571 try 572 { 573 auto& bus = pldm::utils::DBusHandler::getBus(); 574 auto resetMethod = 575 bus.new_method_call(watchDogService, watchDogObjectPath, 576 watchDogInterface, watchDogResetPropName); 577 resetMethod.append(true); 578 bus.call_noreply(resetMethod, dbusTimeout); 579 } 580 catch (const std::exception& e) 581 { 582 error("Failed to reset watchdog timer, error - {ERROR}", "ERROR", e); 583 return; 584 } 585 } 586 587 void pldm::responder::oem_ibm_platform::Handler::disableWatchDogTimer() 588 { 589 setEventReceiverCnt = 0; 590 pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/watchdog/host0", 591 "xyz.openbmc_project.State.Watchdog", 592 "Enabled", "bool"}; 593 bool wdStatus = watchDogRunning(); 594 595 if (!wdStatus) 596 { 597 return; 598 } 599 try 600 { 601 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, false); 602 } 603 catch (const std::exception& e) 604 { 605 error("Failed to disable watchdog timer, error - {ERROR}", "ERROR", e); 606 } 607 } 608 int pldm::responder::oem_ibm_platform::Handler::checkBMCState() 609 { 610 using BMC = sdbusplus::client::xyz::openbmc_project::state::BMC<>; 611 auto bmcPath = sdbusplus::message::object_path(BMC::namespace_path::value) / 612 BMC::namespace_path::bmc; 613 try 614 { 615 pldm::utils::PropertyValue propertyValue = 616 pldm::utils::DBusHandler().getDbusPropertyVariant( 617 bmcPath.str.c_str(), "CurrentBMCState", BMC::interface); 618 619 if (std::get<std::string>(propertyValue) == 620 "xyz.openbmc_project.State.BMC.BMCState.NotReady") 621 { 622 error("GetPDR : PLDM stack is not ready for PDR exchange"); 623 return PLDM_ERROR_NOT_READY; 624 } 625 } 626 catch (const std::exception& e) 627 { 628 error("Error getting the current BMC state, error - {ERROR}", "ERROR", 629 e); 630 return PLDM_ERROR; 631 } 632 return PLDM_SUCCESS; 633 } 634 635 const pldm_pdr_record* 636 pldm::responder::oem_ibm_platform::Handler::fetchLastBMCRecord( 637 const pldm_pdr* repo) 638 { 639 return pldm_pdr_find_last_in_range(repo, BMC_PDR_START_RANGE, 640 BMC_PDR_END_RANGE); 641 } 642 643 bool pldm::responder::oem_ibm_platform::Handler::checkRecordHandleInRange( 644 const uint32_t& record_handle) 645 { 646 return record_handle >= HOST_PDR_START_RANGE && 647 record_handle <= HOST_PDR_END_RANGE; 648 } 649 650 void Handler::processSetEventReceiver() 651 { 652 this->setEventReceiver(); 653 } 654 655 void pldm::responder::oem_ibm_platform::Handler::startStopTimer(bool value) 656 { 657 if (value) 658 { 659 timer.restart( 660 std::chrono::seconds(HEARTBEAT_TIMEOUT + HEARTBEAT_TIMEOUT_DELTA)); 661 } 662 else 663 { 664 timer.setEnabled(value); 665 } 666 } 667 668 void pldm::responder::oem_ibm_platform::Handler::setSurvTimer(uint8_t tid, 669 bool value) 670 { 671 if ((hostOff || hostTransitioningToOff || (tid != HYPERVISOR_TID)) && 672 timer.isEnabled()) 673 { 674 startStopTimer(false); 675 return; 676 } 677 if (value) 678 { 679 startStopTimer(value); 680 } 681 else if (timer.isEnabled()) 682 { 683 info( 684 "Failed to stop surveillance timer while remote terminus status is ‘{HOST_TRANST_OFF}’ with Terminus ID ‘{TID}’ ", 685 "HOST_TRANST_OFF", hostTransitioningToOff, "TID", tid); 686 startStopTimer(value); 687 pldm::utils::reportError( 688 "xyz.openbmc_project.PLDM.Error.setSurvTimer.RecvSurveillancePingFail"); 689 } 690 } 691 692 } // namespace oem_ibm_platform 693 } // namespace responder 694 } // namespace pldm 695