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