1aea5dde1SSampa Misra #include "oem_ibm_handler.hpp"
2aea5dde1SSampa Misra 
3aea5dde1SSampa Misra #include "libpldm/entity.h"
4bb585b28SVarsha Kaverappa #include "libpldm/requester/pldm.h"
5aea5dde1SSampa Misra 
6cfdbca75SSagar Srinivas #include "file_io_type_lid.hpp"
7cfdbca75SSagar Srinivas #include "libpldmresponder/file_io.hpp"
878a225a2SSagar Srinivas #include "libpldmresponder/pdr_utils.hpp"
95079ac4aSBrad Bishop 
105079ac4aSBrad Bishop using namespace pldm::pdr;
115079ac4aSBrad Bishop using namespace pldm::utils;
125079ac4aSBrad Bishop 
13aea5dde1SSampa Misra namespace pldm
14aea5dde1SSampa Misra {
15aea5dde1SSampa Misra namespace responder
16aea5dde1SSampa Misra {
17aea5dde1SSampa Misra namespace oem_ibm_platform
18aea5dde1SSampa Misra {
19aea5dde1SSampa Misra 
20aea5dde1SSampa Misra int pldm::responder::oem_ibm_platform::Handler::
21aea5dde1SSampa Misra     getOemStateSensorReadingsHandler(
22aea5dde1SSampa Misra         EntityType entityType, EntityInstance entityInstance,
23aea5dde1SSampa Misra         StateSetId stateSetId, CompositeCount compSensorCnt,
24aea5dde1SSampa Misra         std::vector<get_sensor_state_field>& stateField)
25aea5dde1SSampa Misra {
26aea5dde1SSampa Misra     int rc = PLDM_SUCCESS;
27aea5dde1SSampa Misra     stateField.clear();
28aea5dde1SSampa Misra 
29aea5dde1SSampa Misra     for (size_t i = 0; i < compSensorCnt; i++)
30aea5dde1SSampa Misra     {
31aea5dde1SSampa Misra         uint8_t sensorOpState{};
3278a225a2SSagar Srinivas         if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
33aea5dde1SSampa Misra             stateSetId == PLDM_OEM_IBM_BOOT_STATE)
34aea5dde1SSampa Misra         {
35aea5dde1SSampa Misra             sensorOpState = fetchBootSide(entityInstance, codeUpdate);
36aea5dde1SSampa Misra         }
37aea5dde1SSampa Misra         else
38aea5dde1SSampa Misra         {
39aea5dde1SSampa Misra             rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
40aea5dde1SSampa Misra             break;
41aea5dde1SSampa Misra         }
42aea5dde1SSampa Misra         stateField.push_back({PLDM_SENSOR_ENABLED, PLDM_SENSOR_UNKNOWN,
43aea5dde1SSampa Misra                               PLDM_SENSOR_UNKNOWN, sensorOpState});
44aea5dde1SSampa Misra     }
45aea5dde1SSampa Misra     return rc;
46aea5dde1SSampa Misra }
47aea5dde1SSampa Misra 
48aea5dde1SSampa Misra int pldm::responder::oem_ibm_platform::Handler::
493a0e3b9bSSampa Misra     oemSetStateEffecterStatesHandler(
503fbd39ebSVarsha Kaverappa         uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
513fbd39ebSVarsha Kaverappa         uint8_t compEffecterCnt,
523fbd39ebSVarsha Kaverappa         std::vector<set_effecter_state_field>& stateField,
533fbd39ebSVarsha Kaverappa         uint16_t /*effecterId*/)
54aea5dde1SSampa Misra {
55aea5dde1SSampa Misra     int rc = PLDM_SUCCESS;
56aea5dde1SSampa Misra 
57aea5dde1SSampa Misra     for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
58aea5dde1SSampa Misra     {
59aea5dde1SSampa Misra         if (stateField[currState].set_request == PLDM_REQUEST_SET)
60aea5dde1SSampa Misra         {
6178a225a2SSagar Srinivas             if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
62aea5dde1SSampa Misra                 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
63aea5dde1SSampa Misra             {
64aea5dde1SSampa Misra                 rc = setBootSide(entityInstance, currState, stateField,
65aea5dde1SSampa Misra                                  codeUpdate);
66aea5dde1SSampa Misra             }
67cfdbca75SSagar Srinivas             else if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
68cfdbca75SSagar Srinivas                      stateSetId == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
69cfdbca75SSagar Srinivas             {
70cfdbca75SSagar Srinivas                 if (stateField[currState].effecter_state ==
71cfdbca75SSagar Srinivas                     uint8_t(CodeUpdateState::START))
72cfdbca75SSagar Srinivas                 {
73cfdbca75SSagar Srinivas                     codeUpdate->setCodeUpdateProgress(true);
743a0e3b9bSSampa Misra                     startUpdateEvent =
753a0e3b9bSSampa Misra                         std::make_unique<sdeventplus::source::Defer>(
763a0e3b9bSSampa Misra                             event,
773a0e3b9bSSampa Misra                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
783a0e3b9bSSampa Misra                                                       _processStartUpdate),
793a0e3b9bSSampa Misra                                       this, std::placeholders::_1));
80cfdbca75SSagar Srinivas                 }
81cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
82cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::END))
83cfdbca75SSagar Srinivas                 {
843a0e3b9bSSampa Misra                     rc = PLDM_SUCCESS;
853a0e3b9bSSampa Misra                     assembleImageEvent = std::make_unique<
863a0e3b9bSSampa Misra                         sdeventplus::source::Defer>(
873a0e3b9bSSampa Misra                         event,
883a0e3b9bSSampa Misra                         std::bind(
893a0e3b9bSSampa Misra                             std::mem_fn(
903a0e3b9bSSampa Misra                                 &oem_ibm_platform::Handler::_processEndUpdate),
913a0e3b9bSSampa Misra                             this, std::placeholders::_1));
923a0e3b9bSSampa Misra 
933a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, END, START);
94cfdbca75SSagar Srinivas                 }
95cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
96cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::ABORT))
97cfdbca75SSagar Srinivas                 {
98cfdbca75SSagar Srinivas                     codeUpdate->setCodeUpdateProgress(false);
99cfdbca75SSagar Srinivas                     codeUpdate->clearDirPath(LID_STAGING_DIR);
1003a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1013a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1023a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::ABORT),
1033a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::START));
1043a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, ABORT, END);
105cfdbca75SSagar Srinivas                 }
106cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
107cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::ACCEPT))
108cfdbca75SSagar Srinivas                 {
1093a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1103a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1113a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::ACCEPT),
1123a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::END));
113cfdbca75SSagar Srinivas                     // TODO Set new Dbus property provided by code update app
1143a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, ACCEPT, END);
115cfdbca75SSagar Srinivas                 }
116cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
117cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::REJECT))
118cfdbca75SSagar Srinivas                 {
1193a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1203a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1213a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::REJECT),
1223a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::END));
123cfdbca75SSagar Srinivas                     // TODO Set new Dbus property provided by code update app
1243a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, REJECT, END);
125cfdbca75SSagar Srinivas                 }
126cfdbca75SSagar Srinivas             }
1279a64b4a7SSagar Srinivas             else if (entityType == PLDM_ENTITY_SYSTEM_CHASSIS &&
1289a64b4a7SSagar Srinivas                      stateSetId == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
1299a64b4a7SSagar Srinivas             {
1309a64b4a7SSagar Srinivas                 if (stateField[currState].effecter_state == POWER_CYCLE_HARD)
1319a64b4a7SSagar Srinivas                 {
1329a64b4a7SSagar Srinivas                     systemRebootEvent =
1339a64b4a7SSagar Srinivas                         std::make_unique<sdeventplus::source::Defer>(
1349a64b4a7SSagar Srinivas                             event,
1359a64b4a7SSagar Srinivas                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
1369a64b4a7SSagar Srinivas                                                       _processSystemReboot),
1379a64b4a7SSagar Srinivas                                       this, std::placeholders::_1));
1389a64b4a7SSagar Srinivas                 }
1399a64b4a7SSagar Srinivas             }
140aea5dde1SSampa Misra             else
141aea5dde1SSampa Misra             {
142aea5dde1SSampa Misra                 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
143aea5dde1SSampa Misra             }
144aea5dde1SSampa Misra         }
145aea5dde1SSampa Misra         if (rc != PLDM_SUCCESS)
146aea5dde1SSampa Misra         {
147aea5dde1SSampa Misra             break;
148aea5dde1SSampa Misra         }
149aea5dde1SSampa Misra     }
150aea5dde1SSampa Misra     return rc;
151aea5dde1SSampa Misra }
152aea5dde1SSampa Misra 
1536b1d8830SManojkiran Eda void buildAllCodeUpdateEffecterPDR(oem_ibm_platform::Handler* platformHandler,
1549a64b4a7SSagar Srinivas                                    uint16_t entityType, uint16_t entityInstance,
1559a64b4a7SSagar Srinivas                                    uint16_t stateSetID, pdr_utils::Repo& repo)
15678a225a2SSagar Srinivas {
15778a225a2SSagar Srinivas     size_t pdrSize = 0;
15878a225a2SSagar Srinivas     pdrSize = sizeof(pldm_state_effecter_pdr) +
15978a225a2SSagar Srinivas               sizeof(state_effecter_possible_states);
16078a225a2SSagar Srinivas     std::vector<uint8_t> entry{};
16178a225a2SSagar Srinivas     entry.resize(pdrSize);
16278a225a2SSagar Srinivas     pldm_state_effecter_pdr* pdr =
16378a225a2SSagar Srinivas         reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
16478a225a2SSagar Srinivas     if (!pdr)
16578a225a2SSagar Srinivas     {
16678a225a2SSagar Srinivas         std::cerr << "Failed to get record by PDR type, ERROR:"
16778a225a2SSagar Srinivas                   << PLDM_PLATFORM_INVALID_EFFECTER_ID << std::endl;
168bcf91accSManojkiran Eda         return;
16978a225a2SSagar Srinivas     }
17078a225a2SSagar Srinivas     pdr->hdr.record_handle = 0;
17178a225a2SSagar Srinivas     pdr->hdr.version = 1;
17278a225a2SSagar Srinivas     pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
17378a225a2SSagar Srinivas     pdr->hdr.record_change_num = 0;
17478a225a2SSagar Srinivas     pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
175cc5f1586SManojkiran Eda     pdr->terminus_handle = TERMINUS_HANDLE;
17678a225a2SSagar Srinivas     pdr->effecter_id = platformHandler->getNextEffecterId();
1779a64b4a7SSagar Srinivas     pdr->entity_type = entityType;
17878a225a2SSagar Srinivas     pdr->entity_instance = entityInstance;
17997296e03SSagar Srinivas     pdr->container_id = 1;
18078a225a2SSagar Srinivas     pdr->effecter_semantic_id = 0;
18178a225a2SSagar Srinivas     pdr->effecter_init = PLDM_NO_INIT;
18278a225a2SSagar Srinivas     pdr->has_description_pdr = false;
18378a225a2SSagar Srinivas     pdr->composite_effecter_count = 1;
18478a225a2SSagar Srinivas 
18578a225a2SSagar Srinivas     auto* possibleStatesPtr = pdr->possible_states;
18678a225a2SSagar Srinivas     auto possibleStates =
18778a225a2SSagar Srinivas         reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
18878a225a2SSagar Srinivas     possibleStates->state_set_id = stateSetID;
18978a225a2SSagar Srinivas     possibleStates->possible_states_size = 2;
19078a225a2SSagar Srinivas     auto state =
19178a225a2SSagar Srinivas         reinterpret_cast<state_effecter_possible_states*>(possibleStates);
19278a225a2SSagar Srinivas     if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
19378a225a2SSagar Srinivas         state->states[0].byte = 6;
19478a225a2SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
19578a225a2SSagar Srinivas         state->states[0].byte = 126;
1969a64b4a7SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
1979a64b4a7SSagar Srinivas         state->states[0].byte = 2;
19878a225a2SSagar Srinivas     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
19978a225a2SSagar Srinivas     pdrEntry.data = entry.data();
20078a225a2SSagar Srinivas     pdrEntry.size = pdrSize;
20178a225a2SSagar Srinivas     repo.addRecord(pdrEntry);
20278a225a2SSagar Srinivas }
20378a225a2SSagar Srinivas 
2046b1d8830SManojkiran Eda void buildAllCodeUpdateSensorPDR(oem_ibm_platform::Handler* platformHandler,
2053a0e3b9bSSampa Misra                                  uint16_t entityType, uint16_t entityInstance,
2063a0e3b9bSSampa Misra                                  uint16_t stateSetID, pdr_utils::Repo& repo)
20778a225a2SSagar Srinivas {
20878a225a2SSagar Srinivas     size_t pdrSize = 0;
20978a225a2SSagar Srinivas     pdrSize =
21078a225a2SSagar Srinivas         sizeof(pldm_state_sensor_pdr) + sizeof(state_sensor_possible_states);
21178a225a2SSagar Srinivas     std::vector<uint8_t> entry{};
21278a225a2SSagar Srinivas     entry.resize(pdrSize);
21378a225a2SSagar Srinivas     pldm_state_sensor_pdr* pdr =
21478a225a2SSagar Srinivas         reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
21578a225a2SSagar Srinivas     if (!pdr)
21678a225a2SSagar Srinivas     {
21778a225a2SSagar Srinivas         std::cerr << "Failed to get record by PDR type, ERROR:"
21878a225a2SSagar Srinivas                   << PLDM_PLATFORM_INVALID_SENSOR_ID << std::endl;
219bcf91accSManojkiran Eda         return;
22078a225a2SSagar Srinivas     }
22178a225a2SSagar Srinivas     pdr->hdr.record_handle = 0;
22278a225a2SSagar Srinivas     pdr->hdr.version = 1;
22378a225a2SSagar Srinivas     pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
22478a225a2SSagar Srinivas     pdr->hdr.record_change_num = 0;
22578a225a2SSagar Srinivas     pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
226cc5f1586SManojkiran Eda     pdr->terminus_handle = TERMINUS_HANDLE;
22778a225a2SSagar Srinivas     pdr->sensor_id = platformHandler->getNextSensorId();
2283a0e3b9bSSampa Misra     pdr->entity_type = entityType;
22978a225a2SSagar Srinivas     pdr->entity_instance = entityInstance;
23097296e03SSagar Srinivas     pdr->container_id = 1;
23178a225a2SSagar Srinivas     pdr->sensor_init = PLDM_NO_INIT;
23278a225a2SSagar Srinivas     pdr->sensor_auxiliary_names_pdr = false;
23378a225a2SSagar Srinivas     pdr->composite_sensor_count = 1;
23478a225a2SSagar Srinivas 
23578a225a2SSagar Srinivas     auto* possibleStatesPtr = pdr->possible_states;
23678a225a2SSagar Srinivas     auto possibleStates =
23778a225a2SSagar Srinivas         reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
23878a225a2SSagar Srinivas     possibleStates->state_set_id = stateSetID;
23978a225a2SSagar Srinivas     possibleStates->possible_states_size = 2;
24078a225a2SSagar Srinivas     auto state =
24178a225a2SSagar Srinivas         reinterpret_cast<state_sensor_possible_states*>(possibleStates);
2423a0e3b9bSSampa Misra     if ((stateSetID == PLDM_OEM_IBM_BOOT_STATE) ||
2437f9523cdSChristian Geddes         (stateSetID == PLDM_OEM_IBM_VERIFICATION_STATE))
24478a225a2SSagar Srinivas         state->states[0].byte = 6;
24578a225a2SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
24678a225a2SSagar Srinivas         state->states[0].byte = 126;
24778a225a2SSagar Srinivas     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
24878a225a2SSagar Srinivas     pdrEntry.data = entry.data();
24978a225a2SSagar Srinivas     pdrEntry.size = pdrSize;
25078a225a2SSagar Srinivas     repo.addRecord(pdrEntry);
25178a225a2SSagar Srinivas }
25278a225a2SSagar Srinivas 
25378a225a2SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
25478a225a2SSagar Srinivas     pdr_utils::Repo& repo)
25578a225a2SSagar Srinivas {
2566b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2576b1d8830SManojkiran Eda                                   ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
2586b1d8830SManojkiran Eda                                   repo);
2596b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2606b1d8830SManojkiran Eda                                   ENTITY_INSTANCE_1, PLDM_OEM_IBM_BOOT_STATE,
2616b1d8830SManojkiran Eda                                   repo);
2626b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2636b1d8830SManojkiran Eda                                   ENTITY_INSTANCE_0,
26478a225a2SSagar Srinivas                                   PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
2656b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_ENTITY_SYSTEM_CHASSIS,
2669a64b4a7SSagar Srinivas                                   ENTITY_INSTANCE_0,
2679a64b4a7SSagar Srinivas                                   PLDM_OEM_IBM_SYSTEM_POWER_STATE, repo);
26878a225a2SSagar Srinivas 
2696b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2706b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
2716b1d8830SManojkiran Eda                                 repo);
2726b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2736b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_1, PLDM_OEM_IBM_BOOT_STATE,
2746b1d8830SManojkiran Eda                                 repo);
2756b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2766b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_0,
27778a225a2SSagar Srinivas                                 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
2786b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2796b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_0,
2803a0e3b9bSSampa Misra                                 PLDM_OEM_IBM_VERIFICATION_STATE, repo);
2813a0e3b9bSSampa Misra     auto sensorId = findStateSensorId(
2823a0e3b9bSSampa Misra         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
283*f4a7dd79SSagar Srinivas         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_VERIFICATION_STATE);
2843a0e3b9bSSampa Misra     codeUpdate->setMarkerLidSensor(sensorId);
2853a0e3b9bSSampa Misra     sensorId = findStateSensorId(
2863a0e3b9bSSampa Misra         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
287*f4a7dd79SSagar Srinivas         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE);
2883a0e3b9bSSampa Misra     codeUpdate->setFirmwareUpdateSensor(sensorId);
28978a225a2SSagar Srinivas }
29078a225a2SSagar Srinivas 
291aea5dde1SSampa Misra void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
292aea5dde1SSampa Misra     pldm::responder::platform::Handler* handler)
293aea5dde1SSampa Misra {
294aea5dde1SSampa Misra     platformHandler = handler;
295aea5dde1SSampa Misra }
296aea5dde1SSampa Misra 
297bb585b28SVarsha Kaverappa int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
298c0c79481SSampa Misra     std::vector<uint8_t>& requestMsg, uint8_t instanceId)
299bb585b28SVarsha Kaverappa {
300bb585b28SVarsha Kaverappa     if (requestMsg.size())
301bb585b28SVarsha Kaverappa     {
302bb585b28SVarsha Kaverappa         std::ostringstream tempStream;
303bb585b28SVarsha Kaverappa         for (int byte : requestMsg)
304bb585b28SVarsha Kaverappa         {
305bb585b28SVarsha Kaverappa             tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
306bb585b28SVarsha Kaverappa                        << " ";
307bb585b28SVarsha Kaverappa         }
308bb585b28SVarsha Kaverappa         std::cout << tempStream.str() << std::endl;
309bb585b28SVarsha Kaverappa     }
310c0c79481SSampa Misra     auto oemPlatformEventMessageResponseHandler =
311c0c79481SSampa Misra         [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
312bb585b28SVarsha Kaverappa             uint8_t completionCode{};
313bb585b28SVarsha Kaverappa             uint8_t status{};
314bb585b28SVarsha Kaverappa             auto rc = decode_platform_event_message_resp(
315c0c79481SSampa Misra                 response, respMsgLen, &completionCode, &status);
316c0c79481SSampa Misra             if (rc || completionCode)
317bb585b28SVarsha Kaverappa             {
318c0c79481SSampa Misra                 std::cerr << "Failed to decode_platform_event_message_resp: "
319c0c79481SSampa Misra                           << " for code update event rc=" << rc
320c0c79481SSampa Misra                           << ", cc=" << static_cast<unsigned>(completionCode)
321c0c79481SSampa Misra                           << std::endl;
322bb585b28SVarsha Kaverappa             }
323c0c79481SSampa Misra         };
324c0c79481SSampa Misra     auto rc = handler->registerRequest(
325c0c79481SSampa Misra         mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
326c0c79481SSampa Misra         std::move(requestMsg),
327c0c79481SSampa Misra         std::move(oemPlatformEventMessageResponseHandler));
328c0c79481SSampa Misra     if (rc)
329c0c79481SSampa Misra     {
330c0c79481SSampa Misra         std::cerr << "Failed to send BIOS attribute change event message \n";
331c0c79481SSampa Misra     }
332c0c79481SSampa Misra 
3333a0e3b9bSSampa Misra     return rc;
3343a0e3b9bSSampa Misra }
3353a0e3b9bSSampa Misra 
3363a0e3b9bSSampa Misra int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
3373a0e3b9bSSampa Misra                    std::vector<uint8_t>& requestMsg, uint8_t instanceId)
3383a0e3b9bSSampa Misra {
3393a0e3b9bSSampa Misra     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
3403a0e3b9bSSampa Misra 
3413a0e3b9bSSampa Misra     auto rc = encode_platform_event_message_req(
3423a0e3b9bSSampa Misra         instanceId, 1 /*formatVersion*/, 0 /*tId*/, eventType,
3433a0e3b9bSSampa Misra         eventDataVec.data(), eventDataVec.size(), request,
3443a0e3b9bSSampa Misra         eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
345bb585b28SVarsha Kaverappa 
346bb585b28SVarsha Kaverappa     return rc;
347bb585b28SVarsha Kaverappa }
348bb585b28SVarsha Kaverappa 
349bb585b28SVarsha Kaverappa void pldm::responder::oem_ibm_platform::Handler::sendStateSensorEvent(
350bb585b28SVarsha Kaverappa     uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
351bb585b28SVarsha Kaverappa     uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
352bb585b28SVarsha Kaverappa {
353bb585b28SVarsha Kaverappa     std::vector<uint8_t> sensorEventDataVec{};
354bb585b28SVarsha Kaverappa     size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
355bb585b28SVarsha Kaverappa     sensorEventDataVec.resize(sensorEventSize);
356bb585b28SVarsha Kaverappa     auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>(
357bb585b28SVarsha Kaverappa         sensorEventDataVec.data());
358bb585b28SVarsha Kaverappa     eventData->sensor_id = sensorId;
359bb585b28SVarsha Kaverappa     eventData->sensor_event_class_type = sensorEventClass;
360bb585b28SVarsha Kaverappa     auto eventClassStart = eventData->event_class;
361bb585b28SVarsha Kaverappa     auto eventClass =
362bb585b28SVarsha Kaverappa         reinterpret_cast<struct pldm_sensor_event_state_sensor_state*>(
363bb585b28SVarsha Kaverappa             eventClassStart);
364bb585b28SVarsha Kaverappa     eventClass->sensor_offset = sensorOffset;
365bb585b28SVarsha Kaverappa     eventClass->event_state = eventState;
366bb585b28SVarsha Kaverappa     eventClass->previous_event_state = prevEventState;
367bb585b28SVarsha Kaverappa     auto instanceId = requester.getInstanceId(mctp_eid);
368bb585b28SVarsha Kaverappa     std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
369bb585b28SVarsha Kaverappa                                     PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
370bb585b28SVarsha Kaverappa                                     sensorEventDataVec.size());
371bb585b28SVarsha Kaverappa     auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
372bb585b28SVarsha Kaverappa                              instanceId);
373bb585b28SVarsha Kaverappa     if (rc != PLDM_SUCCESS)
374bb585b28SVarsha Kaverappa     {
375bb585b28SVarsha Kaverappa         std::cerr << "Failed to encode state sensor event, rc = " << rc
376bb585b28SVarsha Kaverappa                   << std::endl;
377c0c79481SSampa Misra         requester.markFree(mctp_eid, instanceId);
378bb585b28SVarsha Kaverappa         return;
379bb585b28SVarsha Kaverappa     }
380c0c79481SSampa Misra     rc = sendEventToHost(requestMsg, instanceId);
381bb585b28SVarsha Kaverappa     if (rc != PLDM_SUCCESS)
382bb585b28SVarsha Kaverappa     {
383bb585b28SVarsha Kaverappa         std::cerr << "Failed to send event to host: "
384bb585b28SVarsha Kaverappa                   << "rc=" << rc << std::endl;
385bb585b28SVarsha Kaverappa     }
386bb585b28SVarsha Kaverappa     return;
387bb585b28SVarsha Kaverappa }
388bb585b28SVarsha Kaverappa 
3893a0e3b9bSSampa Misra void pldm::responder::oem_ibm_platform::Handler::_processEndUpdate(
3903a0e3b9bSSampa Misra     sdeventplus::source::EventBase& /*source */)
391bb585b28SVarsha Kaverappa {
3923a0e3b9bSSampa Misra     assembleImageEvent.reset();
3939296f244SAdriana Kobylak     int retc = codeUpdate->assembleCodeUpdateImage();
3943a0e3b9bSSampa Misra     if (retc != PLDM_SUCCESS)
3953a0e3b9bSSampa Misra     {
3963a0e3b9bSSampa Misra         codeUpdate->setCodeUpdateProgress(false);
3973a0e3b9bSSampa Misra         auto sensorId = codeUpdate->getFirmwareUpdateSensor();
3983a0e3b9bSSampa Misra         sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
3993a0e3b9bSSampa Misra                              uint8_t(CodeUpdateState::FAIL),
4003a0e3b9bSSampa Misra                              uint8_t(CodeUpdateState::START));
4013a0e3b9bSSampa Misra     }
4023a0e3b9bSSampa Misra }
403bb585b28SVarsha Kaverappa 
4043a0e3b9bSSampa Misra void pldm::responder::oem_ibm_platform::Handler::_processStartUpdate(
4053a0e3b9bSSampa Misra     sdeventplus::source::EventBase& /*source */)
4063a0e3b9bSSampa Misra {
4073a0e3b9bSSampa Misra     codeUpdate->deleteImage();
4083a0e3b9bSSampa Misra     CodeUpdateState state = CodeUpdateState::START;
4093a0e3b9bSSampa Misra     auto rc = codeUpdate->setRequestedApplyTime();
4103a0e3b9bSSampa Misra     if (rc != PLDM_SUCCESS)
4113a0e3b9bSSampa Misra     {
4123a0e3b9bSSampa Misra         std::cerr << "setRequestedApplyTime failed \n";
4133a0e3b9bSSampa Misra         state = CodeUpdateState::FAIL;
4143a0e3b9bSSampa Misra     }
4153a0e3b9bSSampa Misra     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
4163a0e3b9bSSampa Misra     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0, uint8_t(state),
4173a0e3b9bSSampa Misra                          uint8_t(CodeUpdateState::END));
418bb585b28SVarsha Kaverappa }
419bb585b28SVarsha Kaverappa 
4209a64b4a7SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::_processSystemReboot(
4219a64b4a7SSagar Srinivas     sdeventplus::source::EventBase& /*source */)
4229a64b4a7SSagar Srinivas {
4239a64b4a7SSagar Srinivas     pldm::utils::PropertyValue value =
4249a64b4a7SSagar Srinivas         "xyz.openbmc_project.State.Chassis.Transition.Off";
4259a64b4a7SSagar Srinivas     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/state/chassis0",
4269a64b4a7SSagar Srinivas                                          "xyz.openbmc_project.State.Chassis",
4279a64b4a7SSagar Srinivas                                          "RequestedPowerTransition", "string"};
4289a64b4a7SSagar Srinivas     try
4299a64b4a7SSagar Srinivas     {
4309a64b4a7SSagar Srinivas         dBusIntf->setDbusProperty(dbusMapping, value);
4319a64b4a7SSagar Srinivas     }
4329a64b4a7SSagar Srinivas     catch (const std::exception& e)
4339a64b4a7SSagar Srinivas     {
4349a64b4a7SSagar Srinivas 
4359a64b4a7SSagar Srinivas         std::cerr << "Chassis State transition to Off failed,"
4369a64b4a7SSagar Srinivas                   << "unable to set property RequestedPowerTransition"
4379a64b4a7SSagar Srinivas                   << "ERROR=" << e.what() << "\n";
4389a64b4a7SSagar Srinivas     }
4399a64b4a7SSagar Srinivas 
4409a64b4a7SSagar Srinivas     using namespace sdbusplus::bus::match::rules;
4419a64b4a7SSagar Srinivas     chassisOffMatch = std::make_unique<sdbusplus::bus::match::match>(
4429a64b4a7SSagar Srinivas         pldm::utils::DBusHandler::getBus(),
4439a64b4a7SSagar Srinivas         propertiesChanged("/xyz/openbmc_project/state/chassis0",
4449a64b4a7SSagar Srinivas                           "xyz.openbmc_project.State.Chassis"),
4459a64b4a7SSagar Srinivas         [this](sdbusplus::message::message& msg) {
4469a64b4a7SSagar Srinivas             DbusChangedProps props{};
4479a64b4a7SSagar Srinivas             std::string intf;
4489a64b4a7SSagar Srinivas             msg.read(intf, props);
4499a64b4a7SSagar Srinivas             const auto itr = props.find("CurrentPowerState");
4509a64b4a7SSagar Srinivas             if (itr != props.end())
4519a64b4a7SSagar Srinivas             {
4529a64b4a7SSagar Srinivas                 PropertyValue value = itr->second;
4539a64b4a7SSagar Srinivas                 auto propVal = std::get<std::string>(value);
4549a64b4a7SSagar Srinivas                 if (propVal ==
4559a64b4a7SSagar Srinivas                     "xyz.openbmc_project.State.Chassis.PowerState.Off")
4569a64b4a7SSagar Srinivas                 {
4579a64b4a7SSagar Srinivas                     pldm::utils::DBusMapping dbusMapping{
4589a64b4a7SSagar Srinivas                         "/xyz/openbmc_project/control/host0/"
4599a64b4a7SSagar Srinivas                         "power_restore_policy/one_time",
4609a64b4a7SSagar Srinivas                         "xyz.openbmc_project.Control.Power.RestorePolicy",
4619a64b4a7SSagar Srinivas                         "PowerRestorePolicy", "string"};
4629a64b4a7SSagar Srinivas                     value = "xyz.openbmc_project.Control.Power.RestorePolicy."
4639a64b4a7SSagar Srinivas                             "Policy.AlwaysOn";
4649a64b4a7SSagar Srinivas                     try
4659a64b4a7SSagar Srinivas                     {
4669a64b4a7SSagar Srinivas                         dBusIntf->setDbusProperty(dbusMapping, value);
4679a64b4a7SSagar Srinivas                     }
4689a64b4a7SSagar Srinivas                     catch (const std::exception& e)
4699a64b4a7SSagar Srinivas                     {
4709a64b4a7SSagar Srinivas                         std::cerr << "Setting one-time restore policy failed,"
4719a64b4a7SSagar Srinivas                                   << "unable to set property PowerRestorePolicy"
4729a64b4a7SSagar Srinivas                                   << "ERROR=" << e.what() << "\n";
4739a64b4a7SSagar Srinivas                     }
4749a64b4a7SSagar Srinivas                     dbusMapping = pldm::utils::DBusMapping{
4759a64b4a7SSagar Srinivas                         "/xyz/openbmc_project/state/bmc0",
4769a64b4a7SSagar Srinivas                         "xyz.openbmc_project.State.BMC",
4779a64b4a7SSagar Srinivas                         "RequestedBMCTransition", "string"};
4789a64b4a7SSagar Srinivas                     value = "xyz.openbmc_project.State.BMC.Transition.Reboot";
4799a64b4a7SSagar Srinivas                     try
4809a64b4a7SSagar Srinivas                     {
4819a64b4a7SSagar Srinivas                         dBusIntf->setDbusProperty(dbusMapping, value);
4829a64b4a7SSagar Srinivas                     }
4839a64b4a7SSagar Srinivas                     catch (const std::exception& e)
4849a64b4a7SSagar Srinivas                     {
4859a64b4a7SSagar Srinivas                         std::cerr << "BMC state transition to reboot failed,"
4869a64b4a7SSagar Srinivas                                   << "unable to set property "
4879a64b4a7SSagar Srinivas                                      "RequestedBMCTransition"
4889a64b4a7SSagar Srinivas                                   << "ERROR=" << e.what() << "\n";
4899a64b4a7SSagar Srinivas                     }
4909a64b4a7SSagar Srinivas                 }
4919a64b4a7SSagar Srinivas             }
4929a64b4a7SSagar Srinivas         });
4939a64b4a7SSagar Srinivas }
49479669c94SSagar Srinivas 
4957f760b36SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::checkAndDisableWatchDog()
4967f760b36SSagar Srinivas {
4977f760b36SSagar Srinivas     if (!hostOff && setEventReceiverCnt == SET_EVENT_RECEIVER_SENT)
4987f760b36SSagar Srinivas     {
4997f760b36SSagar Srinivas         disableWatchDogTimer();
5007f760b36SSagar Srinivas     }
5017f760b36SSagar Srinivas 
5027f760b36SSagar Srinivas     return;
5037f760b36SSagar Srinivas }
5047f760b36SSagar Srinivas 
50579669c94SSagar Srinivas bool pldm::responder::oem_ibm_platform::Handler::watchDogRunning()
50679669c94SSagar Srinivas {
50779669c94SSagar Srinivas     static constexpr auto watchDogObjectPath =
50879669c94SSagar Srinivas         "/xyz/openbmc_project/watchdog/host0";
50979669c94SSagar Srinivas     static constexpr auto watchDogEnablePropName = "Enabled";
51079669c94SSagar Srinivas     static constexpr auto watchDogInterface =
51179669c94SSagar Srinivas         "xyz.openbmc_project.State.Watchdog";
51279669c94SSagar Srinivas     bool isWatchDogRunning = false;
51379669c94SSagar Srinivas     try
51479669c94SSagar Srinivas     {
51579669c94SSagar Srinivas         isWatchDogRunning = pldm::utils::DBusHandler().getDbusProperty<bool>(
51679669c94SSagar Srinivas             watchDogObjectPath, watchDogEnablePropName, watchDogInterface);
51779669c94SSagar Srinivas     }
51879669c94SSagar Srinivas     catch (const std::exception& e)
51979669c94SSagar Srinivas     {
52079669c94SSagar Srinivas         return false;
52179669c94SSagar Srinivas     }
52279669c94SSagar Srinivas     return isWatchDogRunning;
52379669c94SSagar Srinivas }
52479669c94SSagar Srinivas 
52579669c94SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::resetWatchDogTimer()
52679669c94SSagar Srinivas {
52779669c94SSagar Srinivas     static constexpr auto watchDogService = "xyz.openbmc_project.Watchdog";
52879669c94SSagar Srinivas     static constexpr auto watchDogObjectPath =
52979669c94SSagar Srinivas         "/xyz/openbmc_project/watchdog/host0";
53079669c94SSagar Srinivas     static constexpr auto watchDogInterface =
53179669c94SSagar Srinivas         "xyz.openbmc_project.State.Watchdog";
53279669c94SSagar Srinivas     static constexpr auto watchDogResetPropName = "ResetTimeRemaining";
53379669c94SSagar Srinivas 
53479669c94SSagar Srinivas     bool wdStatus = watchDogRunning();
53579669c94SSagar Srinivas     if (wdStatus == false)
53679669c94SSagar Srinivas     {
53779669c94SSagar Srinivas         return;
53879669c94SSagar Srinivas     }
53979669c94SSagar Srinivas     try
54079669c94SSagar Srinivas     {
54179669c94SSagar Srinivas         auto& bus = pldm::utils::DBusHandler::getBus();
54279669c94SSagar Srinivas         auto resetMethod =
54379669c94SSagar Srinivas             bus.new_method_call(watchDogService, watchDogObjectPath,
54479669c94SSagar Srinivas                                 watchDogInterface, watchDogResetPropName);
54579669c94SSagar Srinivas         resetMethod.append(true);
54679669c94SSagar Srinivas         bus.call_noreply(resetMethod);
54779669c94SSagar Srinivas     }
54879669c94SSagar Srinivas     catch (const std::exception& e)
54979669c94SSagar Srinivas     {
55079669c94SSagar Srinivas         std::cerr << "Failed To reset watchdog timer"
55179669c94SSagar Srinivas                   << "ERROR=" << e.what() << std::endl;
55279669c94SSagar Srinivas         return;
55379669c94SSagar Srinivas     }
55479669c94SSagar Srinivas }
5557f760b36SSagar Srinivas 
5567f760b36SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::disableWatchDogTimer()
5577f760b36SSagar Srinivas {
5587f760b36SSagar Srinivas     setEventReceiverCnt = 0;
5597f760b36SSagar Srinivas     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/watchdog/host0",
5607f760b36SSagar Srinivas                                          "xyz.openbmc_project.State.Watchdog",
5617f760b36SSagar Srinivas                                          "Enabled", "bool"};
5627f760b36SSagar Srinivas     bool wdStatus = watchDogRunning();
5637f760b36SSagar Srinivas 
5647f760b36SSagar Srinivas     if (!wdStatus)
5657f760b36SSagar Srinivas     {
5667f760b36SSagar Srinivas         return;
5677f760b36SSagar Srinivas     }
5687f760b36SSagar Srinivas     try
5697f760b36SSagar Srinivas     {
5707f760b36SSagar Srinivas         pldm::utils::DBusHandler().setDbusProperty(dbusMapping, false);
5717f760b36SSagar Srinivas     }
5727f760b36SSagar Srinivas     catch (const std::exception& e)
5737f760b36SSagar Srinivas     {
5747f760b36SSagar Srinivas         std::cerr << "Failed To disable watchdog timer"
5757f760b36SSagar Srinivas                   << "ERROR=" << e.what() << "\n";
5767f760b36SSagar Srinivas     }
5777f760b36SSagar Srinivas }
57899854a70SPavithra Barithaya int pldm::responder::oem_ibm_platform::Handler::checkBMCState()
57999854a70SPavithra Barithaya {
58099854a70SPavithra Barithaya     try
58199854a70SPavithra Barithaya     {
58299854a70SPavithra Barithaya         pldm::utils::PropertyValue propertyValue =
58399854a70SPavithra Barithaya             pldm::utils::DBusHandler().getDbusPropertyVariant(
58499854a70SPavithra Barithaya                 "/xyz/openbmc_project/state/bmc0", "CurrentBMCState",
58599854a70SPavithra Barithaya                 "xyz.openbmc_project.State.BMC");
58699854a70SPavithra Barithaya 
58799854a70SPavithra Barithaya         if (std::get<std::string>(propertyValue) ==
58899854a70SPavithra Barithaya             "xyz.openbmc_project.State.BMC.BMCState.NotReady")
58999854a70SPavithra Barithaya         {
59099854a70SPavithra Barithaya             std::cerr << "GetPDR : PLDM stack is not ready for PDR exchange"
59199854a70SPavithra Barithaya                       << std::endl;
59299854a70SPavithra Barithaya             return PLDM_ERROR_NOT_READY;
59399854a70SPavithra Barithaya         }
59499854a70SPavithra Barithaya     }
59599854a70SPavithra Barithaya     catch (const std::exception& e)
59699854a70SPavithra Barithaya     {
59799854a70SPavithra Barithaya         std::cerr << "Error getting the current BMC state" << std::endl;
59899854a70SPavithra Barithaya         return PLDM_ERROR;
59999854a70SPavithra Barithaya     }
60099854a70SPavithra Barithaya     return PLDM_SUCCESS;
60199854a70SPavithra Barithaya }
60299854a70SPavithra Barithaya 
603aea5dde1SSampa Misra } // namespace oem_ibm_platform
604aea5dde1SSampa Misra } // namespace responder
605aea5dde1SSampa Misra } // namespace pldm
606