1aea5dde1SSampa Misra #include "oem_ibm_handler.hpp"
2aea5dde1SSampa Misra 
3cfdbca75SSagar Srinivas #include "file_io_type_lid.hpp"
4cfdbca75SSagar Srinivas #include "libpldmresponder/file_io.hpp"
578a225a2SSagar Srinivas #include "libpldmresponder/pdr_utils.hpp"
65079ac4aSBrad Bishop 
7c453e164SGeorge Liu #include <libpldm/entity.h>
827403f46SBrad Bishop #include <libpldm/entity_oem_ibm.h>
927403f46SBrad Bishop 
1049cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
1149cfb138SRiya Dixit 
1249cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
1349cfb138SRiya Dixit 
145079ac4aSBrad Bishop using namespace pldm::pdr;
155079ac4aSBrad Bishop using namespace pldm::utils;
165079ac4aSBrad Bishop 
17aea5dde1SSampa Misra namespace pldm
18aea5dde1SSampa Misra {
19aea5dde1SSampa Misra namespace responder
20aea5dde1SSampa Misra {
21aea5dde1SSampa Misra namespace oem_ibm_platform
22aea5dde1SSampa Misra {
23aea5dde1SSampa Misra int pldm::responder::oem_ibm_platform::Handler::
24aea5dde1SSampa Misra     getOemStateSensorReadingsHandler(
25aea5dde1SSampa Misra         EntityType entityType, EntityInstance entityInstance,
26aea5dde1SSampa Misra         StateSetId stateSetId, CompositeCount compSensorCnt,
27aea5dde1SSampa Misra         std::vector<get_sensor_state_field>& stateField)
28aea5dde1SSampa Misra {
29aea5dde1SSampa Misra     int rc = PLDM_SUCCESS;
30aea5dde1SSampa Misra     stateField.clear();
31aea5dde1SSampa Misra 
32aea5dde1SSampa Misra     for (size_t i = 0; i < compSensorCnt; i++)
33aea5dde1SSampa Misra     {
34aea5dde1SSampa Misra         uint8_t sensorOpState{};
3578a225a2SSagar Srinivas         if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
36aea5dde1SSampa Misra             stateSetId == PLDM_OEM_IBM_BOOT_STATE)
37aea5dde1SSampa Misra         {
38aea5dde1SSampa Misra             sensorOpState = fetchBootSide(entityInstance, codeUpdate);
39aea5dde1SSampa Misra         }
40aea5dde1SSampa Misra         else
41aea5dde1SSampa Misra         {
42aea5dde1SSampa Misra             rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
43aea5dde1SSampa Misra             break;
44aea5dde1SSampa Misra         }
45aea5dde1SSampa Misra         stateField.push_back({PLDM_SENSOR_ENABLED, PLDM_SENSOR_UNKNOWN,
46aea5dde1SSampa Misra                               PLDM_SENSOR_UNKNOWN, sensorOpState});
47aea5dde1SSampa Misra     }
48aea5dde1SSampa Misra     return rc;
49aea5dde1SSampa Misra }
50aea5dde1SSampa Misra 
51aea5dde1SSampa Misra int pldm::responder::oem_ibm_platform::Handler::
523a0e3b9bSSampa Misra     oemSetStateEffecterStatesHandler(
533fbd39ebSVarsha Kaverappa         uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
543fbd39ebSVarsha Kaverappa         uint8_t compEffecterCnt,
553fbd39ebSVarsha Kaverappa         std::vector<set_effecter_state_field>& stateField,
563fbd39ebSVarsha Kaverappa         uint16_t /*effecterId*/)
57aea5dde1SSampa Misra {
58aea5dde1SSampa Misra     int rc = PLDM_SUCCESS;
59aea5dde1SSampa Misra 
60aea5dde1SSampa Misra     for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
61aea5dde1SSampa Misra     {
62aea5dde1SSampa Misra         if (stateField[currState].set_request == PLDM_REQUEST_SET)
63aea5dde1SSampa Misra         {
6478a225a2SSagar Srinivas             if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
65aea5dde1SSampa Misra                 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
66aea5dde1SSampa Misra             {
67aea5dde1SSampa Misra                 rc = setBootSide(entityInstance, currState, stateField,
68aea5dde1SSampa Misra                                  codeUpdate);
69aea5dde1SSampa Misra             }
70cfdbca75SSagar Srinivas             else if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
71cfdbca75SSagar Srinivas                      stateSetId == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
72cfdbca75SSagar Srinivas             {
73cfdbca75SSagar Srinivas                 if (stateField[currState].effecter_state ==
74cfdbca75SSagar Srinivas                     uint8_t(CodeUpdateState::START))
75cfdbca75SSagar Srinivas                 {
76cfdbca75SSagar Srinivas                     codeUpdate->setCodeUpdateProgress(true);
773a0e3b9bSSampa Misra                     startUpdateEvent =
783a0e3b9bSSampa Misra                         std::make_unique<sdeventplus::source::Defer>(
793a0e3b9bSSampa Misra                             event,
803a0e3b9bSSampa Misra                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
813a0e3b9bSSampa Misra                                                       _processStartUpdate),
823a0e3b9bSSampa Misra                                       this, std::placeholders::_1));
83cfdbca75SSagar Srinivas                 }
84cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
85cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::END))
86cfdbca75SSagar Srinivas                 {
873a0e3b9bSSampa Misra                     rc = PLDM_SUCCESS;
883a0e3b9bSSampa Misra                     assembleImageEvent = std::make_unique<
893a0e3b9bSSampa Misra                         sdeventplus::source::Defer>(
903a0e3b9bSSampa Misra                         event,
913a0e3b9bSSampa Misra                         std::bind(
923a0e3b9bSSampa Misra                             std::mem_fn(
933a0e3b9bSSampa Misra                                 &oem_ibm_platform::Handler::_processEndUpdate),
943a0e3b9bSSampa Misra                             this, std::placeholders::_1));
953a0e3b9bSSampa Misra 
963a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, END, START);
97cfdbca75SSagar Srinivas                 }
98cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
99cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::ABORT))
100cfdbca75SSagar Srinivas                 {
101cfdbca75SSagar Srinivas                     codeUpdate->setCodeUpdateProgress(false);
102cfdbca75SSagar Srinivas                     codeUpdate->clearDirPath(LID_STAGING_DIR);
1033a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1043a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1053a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::ABORT),
1063a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::START));
1073a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, ABORT, END);
108cfdbca75SSagar Srinivas                 }
109cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
110cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::ACCEPT))
111cfdbca75SSagar Srinivas                 {
1123a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1133a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1143a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::ACCEPT),
1153a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::END));
116cfdbca75SSagar Srinivas                     // TODO Set new Dbus property provided by code update app
1173a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, ACCEPT, END);
118cfdbca75SSagar Srinivas                 }
119cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
120cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::REJECT))
121cfdbca75SSagar Srinivas                 {
1223a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1233a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1243a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::REJECT),
1253a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::END));
126cfdbca75SSagar Srinivas                     // TODO Set new Dbus property provided by code update app
1273a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, REJECT, END);
128cfdbca75SSagar Srinivas                 }
129cfdbca75SSagar Srinivas             }
1309a64b4a7SSagar Srinivas             else if (entityType == PLDM_ENTITY_SYSTEM_CHASSIS &&
1319a64b4a7SSagar Srinivas                      stateSetId == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
1329a64b4a7SSagar Srinivas             {
1339a64b4a7SSagar Srinivas                 if (stateField[currState].effecter_state == POWER_CYCLE_HARD)
1349a64b4a7SSagar Srinivas                 {
1359a64b4a7SSagar Srinivas                     systemRebootEvent =
1369a64b4a7SSagar Srinivas                         std::make_unique<sdeventplus::source::Defer>(
1379a64b4a7SSagar Srinivas                             event,
1389a64b4a7SSagar Srinivas                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
1399a64b4a7SSagar Srinivas                                                       _processSystemReboot),
1409a64b4a7SSagar Srinivas                                       this, std::placeholders::_1));
1419a64b4a7SSagar Srinivas                 }
1429a64b4a7SSagar Srinivas             }
143aea5dde1SSampa Misra             else
144aea5dde1SSampa Misra             {
145aea5dde1SSampa Misra                 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
146aea5dde1SSampa Misra             }
147aea5dde1SSampa Misra         }
148aea5dde1SSampa Misra         if (rc != PLDM_SUCCESS)
149aea5dde1SSampa Misra         {
150aea5dde1SSampa Misra             break;
151aea5dde1SSampa Misra         }
152aea5dde1SSampa Misra     }
153aea5dde1SSampa Misra     return rc;
154aea5dde1SSampa Misra }
155aea5dde1SSampa Misra 
1566b1d8830SManojkiran Eda void buildAllCodeUpdateEffecterPDR(oem_ibm_platform::Handler* platformHandler,
1579a64b4a7SSagar Srinivas                                    uint16_t entityType, uint16_t entityInstance,
1589a64b4a7SSagar Srinivas                                    uint16_t stateSetID, pdr_utils::Repo& repo)
15978a225a2SSagar Srinivas {
16078a225a2SSagar Srinivas     size_t pdrSize = 0;
16178a225a2SSagar Srinivas     pdrSize = sizeof(pldm_state_effecter_pdr) +
16278a225a2SSagar Srinivas               sizeof(state_effecter_possible_states);
16378a225a2SSagar Srinivas     std::vector<uint8_t> entry{};
16478a225a2SSagar Srinivas     entry.resize(pdrSize);
16578a225a2SSagar Srinivas     pldm_state_effecter_pdr* pdr =
16678a225a2SSagar Srinivas         reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
16778a225a2SSagar Srinivas     if (!pdr)
16878a225a2SSagar Srinivas     {
16949cfb138SRiya Dixit         error("Failed to get record by PDR type, ERROR:{ERR_CODE}", "ERR_CODE",
17049cfb138SRiya Dixit               lg2::hex,
17149cfb138SRiya Dixit               static_cast<unsigned>(PLDM_PLATFORM_INVALID_EFFECTER_ID));
172bcf91accSManojkiran Eda         return;
17378a225a2SSagar Srinivas     }
17478a225a2SSagar Srinivas     pdr->hdr.record_handle = 0;
17578a225a2SSagar Srinivas     pdr->hdr.version = 1;
17678a225a2SSagar Srinivas     pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
17778a225a2SSagar Srinivas     pdr->hdr.record_change_num = 0;
17878a225a2SSagar Srinivas     pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
179cc5f1586SManojkiran Eda     pdr->terminus_handle = TERMINUS_HANDLE;
18078a225a2SSagar Srinivas     pdr->effecter_id = platformHandler->getNextEffecterId();
1819a64b4a7SSagar Srinivas     pdr->entity_type = entityType;
18278a225a2SSagar Srinivas     pdr->entity_instance = entityInstance;
18397296e03SSagar Srinivas     pdr->container_id = 1;
18478a225a2SSagar Srinivas     pdr->effecter_semantic_id = 0;
18578a225a2SSagar Srinivas     pdr->effecter_init = PLDM_NO_INIT;
18678a225a2SSagar Srinivas     pdr->has_description_pdr = false;
18778a225a2SSagar Srinivas     pdr->composite_effecter_count = 1;
18878a225a2SSagar Srinivas 
18978a225a2SSagar Srinivas     auto* possibleStatesPtr = pdr->possible_states;
19078a225a2SSagar Srinivas     auto possibleStates =
19178a225a2SSagar Srinivas         reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
19278a225a2SSagar Srinivas     possibleStates->state_set_id = stateSetID;
19378a225a2SSagar Srinivas     possibleStates->possible_states_size = 2;
19478a225a2SSagar Srinivas     auto state =
19578a225a2SSagar Srinivas         reinterpret_cast<state_effecter_possible_states*>(possibleStates);
19678a225a2SSagar Srinivas     if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
19778a225a2SSagar Srinivas         state->states[0].byte = 6;
19878a225a2SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
19978a225a2SSagar Srinivas         state->states[0].byte = 126;
2009a64b4a7SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
2019a64b4a7SSagar Srinivas         state->states[0].byte = 2;
20278a225a2SSagar Srinivas     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
20378a225a2SSagar Srinivas     pdrEntry.data = entry.data();
20478a225a2SSagar Srinivas     pdrEntry.size = pdrSize;
20578a225a2SSagar Srinivas     repo.addRecord(pdrEntry);
20678a225a2SSagar Srinivas }
20778a225a2SSagar Srinivas 
2086b1d8830SManojkiran Eda void buildAllCodeUpdateSensorPDR(oem_ibm_platform::Handler* platformHandler,
2093a0e3b9bSSampa Misra                                  uint16_t entityType, uint16_t entityInstance,
2103a0e3b9bSSampa Misra                                  uint16_t stateSetID, pdr_utils::Repo& repo)
21178a225a2SSagar Srinivas {
21278a225a2SSagar Srinivas     size_t pdrSize = 0;
2136da4f91bSPatrick Williams     pdrSize = sizeof(pldm_state_sensor_pdr) +
2146da4f91bSPatrick Williams               sizeof(state_sensor_possible_states);
21578a225a2SSagar Srinivas     std::vector<uint8_t> entry{};
21678a225a2SSagar Srinivas     entry.resize(pdrSize);
21778a225a2SSagar Srinivas     pldm_state_sensor_pdr* pdr =
21878a225a2SSagar Srinivas         reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
21978a225a2SSagar Srinivas     if (!pdr)
22078a225a2SSagar Srinivas     {
22149cfb138SRiya Dixit         error("Failed to get record by PDR type, ERROR:{ERR_CODE}", "ERR_CODE",
22249cfb138SRiya Dixit               lg2::hex, static_cast<unsigned>(PLDM_PLATFORM_INVALID_SENSOR_ID));
223bcf91accSManojkiran Eda         return;
22478a225a2SSagar Srinivas     }
22578a225a2SSagar Srinivas     pdr->hdr.record_handle = 0;
22678a225a2SSagar Srinivas     pdr->hdr.version = 1;
22778a225a2SSagar Srinivas     pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
22878a225a2SSagar Srinivas     pdr->hdr.record_change_num = 0;
22978a225a2SSagar Srinivas     pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
230cc5f1586SManojkiran Eda     pdr->terminus_handle = TERMINUS_HANDLE;
23178a225a2SSagar Srinivas     pdr->sensor_id = platformHandler->getNextSensorId();
2323a0e3b9bSSampa Misra     pdr->entity_type = entityType;
23378a225a2SSagar Srinivas     pdr->entity_instance = entityInstance;
23497296e03SSagar Srinivas     pdr->container_id = 1;
23578a225a2SSagar Srinivas     pdr->sensor_init = PLDM_NO_INIT;
23678a225a2SSagar Srinivas     pdr->sensor_auxiliary_names_pdr = false;
23778a225a2SSagar Srinivas     pdr->composite_sensor_count = 1;
23878a225a2SSagar Srinivas 
23978a225a2SSagar Srinivas     auto* possibleStatesPtr = pdr->possible_states;
24078a225a2SSagar Srinivas     auto possibleStates =
24178a225a2SSagar Srinivas         reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
24278a225a2SSagar Srinivas     possibleStates->state_set_id = stateSetID;
24378a225a2SSagar Srinivas     possibleStates->possible_states_size = 2;
24478a225a2SSagar Srinivas     auto state =
24578a225a2SSagar Srinivas         reinterpret_cast<state_sensor_possible_states*>(possibleStates);
2463a0e3b9bSSampa Misra     if ((stateSetID == PLDM_OEM_IBM_BOOT_STATE) ||
2477f9523cdSChristian Geddes         (stateSetID == PLDM_OEM_IBM_VERIFICATION_STATE))
24878a225a2SSagar Srinivas         state->states[0].byte = 6;
24978a225a2SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
25078a225a2SSagar Srinivas         state->states[0].byte = 126;
25178a225a2SSagar Srinivas     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
25278a225a2SSagar Srinivas     pdrEntry.data = entry.data();
25378a225a2SSagar Srinivas     pdrEntry.size = pdrSize;
25478a225a2SSagar Srinivas     repo.addRecord(pdrEntry);
25578a225a2SSagar Srinivas }
25678a225a2SSagar Srinivas 
25778a225a2SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
25878a225a2SSagar Srinivas     pdr_utils::Repo& repo)
25978a225a2SSagar Srinivas {
2606b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2616b1d8830SManojkiran Eda                                   ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
2626b1d8830SManojkiran Eda                                   repo);
2636b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2646b1d8830SManojkiran Eda                                   ENTITY_INSTANCE_1, PLDM_OEM_IBM_BOOT_STATE,
2656b1d8830SManojkiran Eda                                   repo);
2666b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2676b1d8830SManojkiran Eda                                   ENTITY_INSTANCE_0,
26878a225a2SSagar Srinivas                                   PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
2696b1d8830SManojkiran Eda     buildAllCodeUpdateEffecterPDR(this, PLDM_ENTITY_SYSTEM_CHASSIS,
2701b8d35f5SSagar Srinivas                                   ENTITY_INSTANCE_1,
2719a64b4a7SSagar Srinivas                                   PLDM_OEM_IBM_SYSTEM_POWER_STATE, repo);
27278a225a2SSagar Srinivas 
2736b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2746b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
2756b1d8830SManojkiran Eda                                 repo);
2766b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2776b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_1, PLDM_OEM_IBM_BOOT_STATE,
2786b1d8830SManojkiran Eda                                 repo);
2796b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2806b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_0,
28178a225a2SSagar Srinivas                                 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
2826b1d8830SManojkiran Eda     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2836b1d8830SManojkiran Eda                                 ENTITY_INSTANCE_0,
2843a0e3b9bSSampa Misra                                 PLDM_OEM_IBM_VERIFICATION_STATE, repo);
2853a0e3b9bSSampa Misra     auto sensorId = findStateSensorId(
2863a0e3b9bSSampa Misra         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
287f4a7dd79SSagar Srinivas         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_VERIFICATION_STATE);
2883a0e3b9bSSampa Misra     codeUpdate->setMarkerLidSensor(sensorId);
2893a0e3b9bSSampa Misra     sensorId = findStateSensorId(
2903a0e3b9bSSampa Misra         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
291f4a7dd79SSagar Srinivas         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE);
2923a0e3b9bSSampa Misra     codeUpdate->setFirmwareUpdateSensor(sensorId);
29378a225a2SSagar Srinivas }
29478a225a2SSagar Srinivas 
295aea5dde1SSampa Misra void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
296aea5dde1SSampa Misra     pldm::responder::platform::Handler* handler)
297aea5dde1SSampa Misra {
298aea5dde1SSampa Misra     platformHandler = handler;
299aea5dde1SSampa Misra }
300aea5dde1SSampa Misra 
301bb585b28SVarsha Kaverappa int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
302c0c79481SSampa Misra     std::vector<uint8_t>& requestMsg, uint8_t instanceId)
303bb585b28SVarsha Kaverappa {
304bb585b28SVarsha Kaverappa     if (requestMsg.size())
305bb585b28SVarsha Kaverappa     {
306bb585b28SVarsha Kaverappa         std::ostringstream tempStream;
307bb585b28SVarsha Kaverappa         for (int byte : requestMsg)
308bb585b28SVarsha Kaverappa         {
309bb585b28SVarsha Kaverappa             tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
310bb585b28SVarsha Kaverappa                        << " ";
311bb585b28SVarsha Kaverappa         }
312bb585b28SVarsha Kaverappa         std::cout << tempStream.str() << std::endl;
313bb585b28SVarsha Kaverappa     }
3146da4f91bSPatrick Williams     auto oemPlatformEventMessageResponseHandler =
3156da4f91bSPatrick Williams         [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
316bb585b28SVarsha Kaverappa         uint8_t completionCode{};
317bb585b28SVarsha Kaverappa         uint8_t status{};
31849cfb138SRiya Dixit         auto rc = decode_platform_event_message_resp(response, respMsgLen,
31949cfb138SRiya Dixit                                                      &completionCode, &status);
320c0c79481SSampa Misra         if (rc || completionCode)
321bb585b28SVarsha Kaverappa         {
32249cfb138SRiya Dixit             error(
32349cfb138SRiya Dixit                 "Failed to decode_platform_event_message_resp: for code update event rc={RC}, cc={CC}",
32449cfb138SRiya Dixit                 "RC", rc, "CC", static_cast<unsigned>(completionCode));
325bb585b28SVarsha Kaverappa         }
326c0c79481SSampa Misra     };
327c0c79481SSampa Misra     auto rc = handler->registerRequest(
328c0c79481SSampa Misra         mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
329c0c79481SSampa Misra         std::move(requestMsg),
330c0c79481SSampa Misra         std::move(oemPlatformEventMessageResponseHandler));
331c0c79481SSampa Misra     if (rc)
332c0c79481SSampa Misra     {
33349cfb138SRiya Dixit         error("Failed to send BIOS attribute change event message ");
334c0c79481SSampa Misra     }
335c0c79481SSampa Misra 
3363a0e3b9bSSampa Misra     return rc;
3373a0e3b9bSSampa Misra }
3383a0e3b9bSSampa Misra 
3393a0e3b9bSSampa Misra int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
3403a0e3b9bSSampa Misra                    std::vector<uint8_t>& requestMsg, uint8_t instanceId)
3413a0e3b9bSSampa Misra {
3423a0e3b9bSSampa Misra     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
3433a0e3b9bSSampa Misra 
3443a0e3b9bSSampa Misra     auto rc = encode_platform_event_message_req(
3456c39c7a7SArchanaKakani         instanceId, 1 /*formatVersion*/, TERMINUS_ID /*tId*/, eventType,
3463a0e3b9bSSampa Misra         eventDataVec.data(), eventDataVec.size(), request,
3473a0e3b9bSSampa Misra         eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
348bb585b28SVarsha Kaverappa 
349bb585b28SVarsha Kaverappa     return rc;
350bb585b28SVarsha Kaverappa }
351bb585b28SVarsha Kaverappa 
352bb585b28SVarsha Kaverappa void pldm::responder::oem_ibm_platform::Handler::sendStateSensorEvent(
353bb585b28SVarsha Kaverappa     uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
354bb585b28SVarsha Kaverappa     uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
355bb585b28SVarsha Kaverappa {
356bb585b28SVarsha Kaverappa     std::vector<uint8_t> sensorEventDataVec{};
357bb585b28SVarsha Kaverappa     size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
358bb585b28SVarsha Kaverappa     sensorEventDataVec.resize(sensorEventSize);
359bb585b28SVarsha Kaverappa     auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>(
360bb585b28SVarsha Kaverappa         sensorEventDataVec.data());
361bb585b28SVarsha Kaverappa     eventData->sensor_id = sensorId;
362bb585b28SVarsha Kaverappa     eventData->sensor_event_class_type = sensorEventClass;
363bb585b28SVarsha Kaverappa     auto eventClassStart = eventData->event_class;
364bb585b28SVarsha Kaverappa     auto eventClass =
365bb585b28SVarsha Kaverappa         reinterpret_cast<struct pldm_sensor_event_state_sensor_state*>(
366bb585b28SVarsha Kaverappa             eventClassStart);
367bb585b28SVarsha Kaverappa     eventClass->sensor_offset = sensorOffset;
368bb585b28SVarsha Kaverappa     eventClass->event_state = eventState;
369bb585b28SVarsha Kaverappa     eventClass->previous_event_state = prevEventState;
370a330b2f0SAndrew Jeffery     auto instanceId = instanceIdDb.next(mctp_eid);
371bb585b28SVarsha Kaverappa     std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
372bb585b28SVarsha Kaverappa                                     PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
373bb585b28SVarsha Kaverappa                                     sensorEventDataVec.size());
374bb585b28SVarsha Kaverappa     auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
375bb585b28SVarsha Kaverappa                              instanceId);
376bb585b28SVarsha Kaverappa     if (rc != PLDM_SUCCESS)
377bb585b28SVarsha Kaverappa     {
37849cfb138SRiya Dixit         error("Failed to encode state sensor event, rc = {RC}", "RC", rc);
379a330b2f0SAndrew Jeffery         instanceIdDb.free(mctp_eid, instanceId);
380bb585b28SVarsha Kaverappa         return;
381bb585b28SVarsha Kaverappa     }
382c0c79481SSampa Misra     rc = sendEventToHost(requestMsg, instanceId);
383bb585b28SVarsha Kaverappa     if (rc != PLDM_SUCCESS)
384bb585b28SVarsha Kaverappa     {
38549cfb138SRiya Dixit         error("Failed to send event to host: rc={RC}", "RC", rc);
386bb585b28SVarsha Kaverappa     }
387bb585b28SVarsha Kaverappa     return;
388bb585b28SVarsha Kaverappa }
389bb585b28SVarsha Kaverappa 
3903a0e3b9bSSampa Misra void pldm::responder::oem_ibm_platform::Handler::_processEndUpdate(
3913a0e3b9bSSampa Misra     sdeventplus::source::EventBase& /*source */)
392bb585b28SVarsha Kaverappa {
3933a0e3b9bSSampa Misra     assembleImageEvent.reset();
3949296f244SAdriana Kobylak     int retc = codeUpdate->assembleCodeUpdateImage();
3953a0e3b9bSSampa Misra     if (retc != PLDM_SUCCESS)
3963a0e3b9bSSampa Misra     {
3973a0e3b9bSSampa Misra         codeUpdate->setCodeUpdateProgress(false);
3983a0e3b9bSSampa Misra         auto sensorId = codeUpdate->getFirmwareUpdateSensor();
3993a0e3b9bSSampa Misra         sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
4003a0e3b9bSSampa Misra                              uint8_t(CodeUpdateState::FAIL),
4013a0e3b9bSSampa Misra                              uint8_t(CodeUpdateState::START));
4023a0e3b9bSSampa Misra     }
4033a0e3b9bSSampa Misra }
404bb585b28SVarsha Kaverappa 
4053a0e3b9bSSampa Misra void pldm::responder::oem_ibm_platform::Handler::_processStartUpdate(
4063a0e3b9bSSampa Misra     sdeventplus::source::EventBase& /*source */)
4073a0e3b9bSSampa Misra {
4083a0e3b9bSSampa Misra     codeUpdate->deleteImage();
4093a0e3b9bSSampa Misra     CodeUpdateState state = CodeUpdateState::START;
4103a0e3b9bSSampa Misra     auto rc = codeUpdate->setRequestedApplyTime();
4113a0e3b9bSSampa Misra     if (rc != PLDM_SUCCESS)
4123a0e3b9bSSampa Misra     {
41349cfb138SRiya Dixit         error("setRequestedApplyTime failed");
4143a0e3b9bSSampa Misra         state = CodeUpdateState::FAIL;
4153a0e3b9bSSampa Misra     }
4163a0e3b9bSSampa Misra     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
4173a0e3b9bSSampa Misra     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0, uint8_t(state),
4183a0e3b9bSSampa Misra                          uint8_t(CodeUpdateState::END));
419bb585b28SVarsha Kaverappa }
420bb585b28SVarsha Kaverappa 
4219a64b4a7SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::_processSystemReboot(
4229a64b4a7SSagar Srinivas     sdeventplus::source::EventBase& /*source */)
4239a64b4a7SSagar Srinivas {
4249a64b4a7SSagar Srinivas     pldm::utils::PropertyValue value =
4259a64b4a7SSagar Srinivas         "xyz.openbmc_project.State.Chassis.Transition.Off";
4269a64b4a7SSagar Srinivas     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/state/chassis0",
4279a64b4a7SSagar Srinivas                                          "xyz.openbmc_project.State.Chassis",
4289a64b4a7SSagar Srinivas                                          "RequestedPowerTransition", "string"};
4299a64b4a7SSagar Srinivas     try
4309a64b4a7SSagar Srinivas     {
4319a64b4a7SSagar Srinivas         dBusIntf->setDbusProperty(dbusMapping, value);
4329a64b4a7SSagar Srinivas     }
4339a64b4a7SSagar Srinivas     catch (const std::exception& e)
4349a64b4a7SSagar Srinivas     {
43549cfb138SRiya Dixit         error(
43649cfb138SRiya Dixit             "Chassis State transition to Off failed, unable to set property RequestedPowerTransition ERROR={ERR_EXCEP}",
43749cfb138SRiya Dixit             "ERR_EXCEP", e.what());
4389a64b4a7SSagar Srinivas     }
4399a64b4a7SSagar Srinivas 
4409a64b4a7SSagar Srinivas     using namespace sdbusplus::bus::match::rules;
44184b790cbSPatrick Williams     chassisOffMatch = std::make_unique<sdbusplus::bus::match_t>(
4429a64b4a7SSagar Srinivas         pldm::utils::DBusHandler::getBus(),
4439a64b4a7SSagar Srinivas         propertiesChanged("/xyz/openbmc_project/state/chassis0",
4449a64b4a7SSagar Srinivas                           "xyz.openbmc_project.State.Chassis"),
44584b790cbSPatrick Williams         [this](sdbusplus::message_t& 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);
4546da4f91bSPatrick Williams             if (propVal == "xyz.openbmc_project.State.Chassis.PowerState.Off")
4559a64b4a7SSagar Srinivas             {
4569a64b4a7SSagar Srinivas                 pldm::utils::DBusMapping dbusMapping{
4579a64b4a7SSagar Srinivas                     "/xyz/openbmc_project/control/host0/"
4589a64b4a7SSagar Srinivas                     "power_restore_policy/one_time",
4599a64b4a7SSagar Srinivas                     "xyz.openbmc_project.Control.Power.RestorePolicy",
4609a64b4a7SSagar Srinivas                     "PowerRestorePolicy", "string"};
4619a64b4a7SSagar Srinivas                 value = "xyz.openbmc_project.Control.Power.RestorePolicy."
4629a64b4a7SSagar Srinivas                         "Policy.AlwaysOn";
4639a64b4a7SSagar Srinivas                 try
4649a64b4a7SSagar Srinivas                 {
4659a64b4a7SSagar Srinivas                     dBusIntf->setDbusProperty(dbusMapping, value);
4669a64b4a7SSagar Srinivas                 }
4679a64b4a7SSagar Srinivas                 catch (const std::exception& e)
4689a64b4a7SSagar Srinivas                 {
46949cfb138SRiya Dixit                     error(
47049cfb138SRiya Dixit                         "Setting one-time restore policy failed, unable to set property PowerRestorePolicy ERROR={ERR_EXCEP}",
47149cfb138SRiya Dixit                         "ERR_EXCEP", e.what());
4729a64b4a7SSagar Srinivas                 }
4739a64b4a7SSagar Srinivas                 dbusMapping = pldm::utils::DBusMapping{
4749a64b4a7SSagar Srinivas                     "/xyz/openbmc_project/state/bmc0",
4756da4f91bSPatrick Williams                     "xyz.openbmc_project.State.BMC", "RequestedBMCTransition",
4766da4f91bSPatrick Williams                     "string"};
4779a64b4a7SSagar Srinivas                 value = "xyz.openbmc_project.State.BMC.Transition.Reboot";
4789a64b4a7SSagar Srinivas                 try
4799a64b4a7SSagar Srinivas                 {
4809a64b4a7SSagar Srinivas                     dBusIntf->setDbusProperty(dbusMapping, value);
4819a64b4a7SSagar Srinivas                 }
4829a64b4a7SSagar Srinivas                 catch (const std::exception& e)
4839a64b4a7SSagar Srinivas                 {
48449cfb138SRiya Dixit                     error(
48549cfb138SRiya Dixit                         "BMC state transition to reboot failed, unable to set property RequestedBMCTransition ERROR={ERR_EXCEP}",
48649cfb138SRiya Dixit                         "ERR_EXCEP", e.what());
4879a64b4a7SSagar Srinivas                 }
4889a64b4a7SSagar Srinivas             }
4899a64b4a7SSagar Srinivas         }
4909a64b4a7SSagar Srinivas     });
4919a64b4a7SSagar Srinivas }
49279669c94SSagar Srinivas 
4937f760b36SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::checkAndDisableWatchDog()
4947f760b36SSagar Srinivas {
4957f760b36SSagar Srinivas     if (!hostOff && setEventReceiverCnt == SET_EVENT_RECEIVER_SENT)
4967f760b36SSagar Srinivas     {
4977f760b36SSagar Srinivas         disableWatchDogTimer();
4987f760b36SSagar Srinivas     }
4997f760b36SSagar Srinivas 
5007f760b36SSagar Srinivas     return;
5017f760b36SSagar Srinivas }
5027f760b36SSagar Srinivas 
50379669c94SSagar Srinivas bool pldm::responder::oem_ibm_platform::Handler::watchDogRunning()
50479669c94SSagar Srinivas {
50579669c94SSagar Srinivas     static constexpr auto watchDogObjectPath =
50679669c94SSagar Srinivas         "/xyz/openbmc_project/watchdog/host0";
50779669c94SSagar Srinivas     static constexpr auto watchDogEnablePropName = "Enabled";
50879669c94SSagar Srinivas     static constexpr auto watchDogInterface =
50979669c94SSagar Srinivas         "xyz.openbmc_project.State.Watchdog";
51079669c94SSagar Srinivas     bool isWatchDogRunning = false;
51179669c94SSagar Srinivas     try
51279669c94SSagar Srinivas     {
51379669c94SSagar Srinivas         isWatchDogRunning = pldm::utils::DBusHandler().getDbusProperty<bool>(
51479669c94SSagar Srinivas             watchDogObjectPath, watchDogEnablePropName, watchDogInterface);
51579669c94SSagar Srinivas     }
51679669c94SSagar Srinivas     catch (const std::exception& e)
51779669c94SSagar Srinivas     {
51879669c94SSagar Srinivas         return false;
51979669c94SSagar Srinivas     }
52079669c94SSagar Srinivas     return isWatchDogRunning;
52179669c94SSagar Srinivas }
52279669c94SSagar Srinivas 
52379669c94SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::resetWatchDogTimer()
52479669c94SSagar Srinivas {
52579669c94SSagar Srinivas     static constexpr auto watchDogService = "xyz.openbmc_project.Watchdog";
52679669c94SSagar Srinivas     static constexpr auto watchDogObjectPath =
52779669c94SSagar Srinivas         "/xyz/openbmc_project/watchdog/host0";
52879669c94SSagar Srinivas     static constexpr auto watchDogInterface =
52979669c94SSagar Srinivas         "xyz.openbmc_project.State.Watchdog";
53079669c94SSagar Srinivas     static constexpr auto watchDogResetPropName = "ResetTimeRemaining";
53179669c94SSagar Srinivas 
53279669c94SSagar Srinivas     bool wdStatus = watchDogRunning();
53379669c94SSagar Srinivas     if (wdStatus == false)
53479669c94SSagar Srinivas     {
53579669c94SSagar Srinivas         return;
53679669c94SSagar Srinivas     }
53779669c94SSagar Srinivas     try
53879669c94SSagar Srinivas     {
53979669c94SSagar Srinivas         auto& bus = pldm::utils::DBusHandler::getBus();
54079669c94SSagar Srinivas         auto resetMethod =
54179669c94SSagar Srinivas             bus.new_method_call(watchDogService, watchDogObjectPath,
54279669c94SSagar Srinivas                                 watchDogInterface, watchDogResetPropName);
54379669c94SSagar Srinivas         resetMethod.append(true);
5445b71b86fSvkaverap@in.ibm.com         bus.call_noreply(resetMethod, dbusTimeout);
54579669c94SSagar Srinivas     }
54679669c94SSagar Srinivas     catch (const std::exception& e)
54779669c94SSagar Srinivas     {
54849cfb138SRiya Dixit         error("Failed To reset watchdog timer ERROR={ERR_EXCEP}", "ERR_EXCEP",
54949cfb138SRiya Dixit               e.what());
55079669c94SSagar Srinivas         return;
55179669c94SSagar Srinivas     }
55279669c94SSagar Srinivas }
5537f760b36SSagar Srinivas 
5547f760b36SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::disableWatchDogTimer()
5557f760b36SSagar Srinivas {
5567f760b36SSagar Srinivas     setEventReceiverCnt = 0;
5577f760b36SSagar Srinivas     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/watchdog/host0",
5587f760b36SSagar Srinivas                                          "xyz.openbmc_project.State.Watchdog",
5597f760b36SSagar Srinivas                                          "Enabled", "bool"};
5607f760b36SSagar Srinivas     bool wdStatus = watchDogRunning();
5617f760b36SSagar Srinivas 
5627f760b36SSagar Srinivas     if (!wdStatus)
5637f760b36SSagar Srinivas     {
5647f760b36SSagar Srinivas         return;
5657f760b36SSagar Srinivas     }
5667f760b36SSagar Srinivas     try
5677f760b36SSagar Srinivas     {
5687f760b36SSagar Srinivas         pldm::utils::DBusHandler().setDbusProperty(dbusMapping, false);
5697f760b36SSagar Srinivas     }
5707f760b36SSagar Srinivas     catch (const std::exception& e)
5717f760b36SSagar Srinivas     {
57249cfb138SRiya Dixit         error("Failed To disable watchdog timer ERROR={ERR_EXCEP}", "ERR_EXCEP",
57349cfb138SRiya Dixit               e.what());
5747f760b36SSagar Srinivas     }
5757f760b36SSagar Srinivas }
57699854a70SPavithra Barithaya int pldm::responder::oem_ibm_platform::Handler::checkBMCState()
57799854a70SPavithra Barithaya {
57899854a70SPavithra Barithaya     try
57999854a70SPavithra Barithaya     {
58099854a70SPavithra Barithaya         pldm::utils::PropertyValue propertyValue =
58199854a70SPavithra Barithaya             pldm::utils::DBusHandler().getDbusPropertyVariant(
58299854a70SPavithra Barithaya                 "/xyz/openbmc_project/state/bmc0", "CurrentBMCState",
58399854a70SPavithra Barithaya                 "xyz.openbmc_project.State.BMC");
58499854a70SPavithra Barithaya 
58599854a70SPavithra Barithaya         if (std::get<std::string>(propertyValue) ==
58699854a70SPavithra Barithaya             "xyz.openbmc_project.State.BMC.BMCState.NotReady")
58799854a70SPavithra Barithaya         {
58849cfb138SRiya Dixit             error("GetPDR : PLDM stack is not ready for PDR exchange");
58999854a70SPavithra Barithaya             return PLDM_ERROR_NOT_READY;
59099854a70SPavithra Barithaya         }
59199854a70SPavithra Barithaya     }
59299854a70SPavithra Barithaya     catch (const std::exception& e)
59399854a70SPavithra Barithaya     {
59449cfb138SRiya Dixit         error("Error getting the current BMC state");
59599854a70SPavithra Barithaya         return PLDM_ERROR;
59699854a70SPavithra Barithaya     }
59799854a70SPavithra Barithaya     return PLDM_SUCCESS;
59899854a70SPavithra Barithaya }
59999854a70SPavithra Barithaya 
6003687e2b6SSagar Srinivas const pldm_pdr_record*
6013687e2b6SSagar Srinivas     pldm::responder::oem_ibm_platform::Handler::fetchLastBMCRecord(
6023687e2b6SSagar Srinivas         const pldm_pdr* repo)
6033687e2b6SSagar Srinivas {
6043687e2b6SSagar Srinivas     return pldm_pdr_find_last_in_range(repo, BMC_PDR_START_RANGE,
6053687e2b6SSagar Srinivas                                        BMC_PDR_END_RANGE);
6063687e2b6SSagar Srinivas }
6073687e2b6SSagar Srinivas 
6083687e2b6SSagar Srinivas bool pldm::responder::oem_ibm_platform::Handler::checkRecordHandleInRange(
6093687e2b6SSagar Srinivas     const uint32_t& record_handle)
6103687e2b6SSagar Srinivas {
6113687e2b6SSagar Srinivas     return record_handle >= HOST_PDR_START_RANGE &&
6123687e2b6SSagar Srinivas            record_handle <= HOST_PDR_END_RANGE;
6133687e2b6SSagar Srinivas }
6143687e2b6SSagar Srinivas 
615*90314a3fSSagar Srinivas void Handler::processSetEventReceiver()
616*90314a3fSSagar Srinivas {
617*90314a3fSSagar Srinivas     this->setEventReceiver();
618*90314a3fSSagar Srinivas }
619*90314a3fSSagar Srinivas 
620aea5dde1SSampa Misra } // namespace oem_ibm_platform
621aea5dde1SSampa Misra } // namespace responder
622aea5dde1SSampa Misra } // namespace pldm
623