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"
9aea5dde1SSampa Misra namespace pldm
10aea5dde1SSampa Misra {
11aea5dde1SSampa Misra namespace responder
12aea5dde1SSampa Misra {
13aea5dde1SSampa Misra namespace oem_ibm_platform
14aea5dde1SSampa Misra {
15aea5dde1SSampa Misra 
16aea5dde1SSampa Misra int pldm::responder::oem_ibm_platform::Handler::
17aea5dde1SSampa Misra     getOemStateSensorReadingsHandler(
18aea5dde1SSampa Misra         EntityType entityType, EntityInstance entityInstance,
19aea5dde1SSampa Misra         StateSetId stateSetId, CompositeCount compSensorCnt,
20aea5dde1SSampa Misra         std::vector<get_sensor_state_field>& stateField)
21aea5dde1SSampa Misra {
22aea5dde1SSampa Misra     int rc = PLDM_SUCCESS;
23aea5dde1SSampa Misra     stateField.clear();
24aea5dde1SSampa Misra 
25aea5dde1SSampa Misra     for (size_t i = 0; i < compSensorCnt; i++)
26aea5dde1SSampa Misra     {
27aea5dde1SSampa Misra         uint8_t sensorOpState{};
2878a225a2SSagar Srinivas         if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
29aea5dde1SSampa Misra             stateSetId == PLDM_OEM_IBM_BOOT_STATE)
30aea5dde1SSampa Misra         {
31aea5dde1SSampa Misra             sensorOpState = fetchBootSide(entityInstance, codeUpdate);
32aea5dde1SSampa Misra         }
33aea5dde1SSampa Misra         else
34aea5dde1SSampa Misra         {
35aea5dde1SSampa Misra             rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
36aea5dde1SSampa Misra             break;
37aea5dde1SSampa Misra         }
38aea5dde1SSampa Misra         stateField.push_back({PLDM_SENSOR_ENABLED, PLDM_SENSOR_UNKNOWN,
39aea5dde1SSampa Misra                               PLDM_SENSOR_UNKNOWN, sensorOpState});
40aea5dde1SSampa Misra     }
41aea5dde1SSampa Misra     return rc;
42aea5dde1SSampa Misra }
43aea5dde1SSampa Misra 
44aea5dde1SSampa Misra int pldm::responder::oem_ibm_platform::Handler::
453a0e3b9bSSampa Misra     oemSetStateEffecterStatesHandler(
463fbd39ebSVarsha Kaverappa         uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
473fbd39ebSVarsha Kaverappa         uint8_t compEffecterCnt,
483fbd39ebSVarsha Kaverappa         std::vector<set_effecter_state_field>& stateField,
493fbd39ebSVarsha Kaverappa         uint16_t /*effecterId*/)
50aea5dde1SSampa Misra {
51aea5dde1SSampa Misra     int rc = PLDM_SUCCESS;
52aea5dde1SSampa Misra 
53aea5dde1SSampa Misra     for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
54aea5dde1SSampa Misra     {
55aea5dde1SSampa Misra         if (stateField[currState].set_request == PLDM_REQUEST_SET)
56aea5dde1SSampa Misra         {
5778a225a2SSagar Srinivas             if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
58aea5dde1SSampa Misra                 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
59aea5dde1SSampa Misra             {
60aea5dde1SSampa Misra                 rc = setBootSide(entityInstance, currState, stateField,
61aea5dde1SSampa Misra                                  codeUpdate);
62aea5dde1SSampa Misra             }
63cfdbca75SSagar Srinivas             else if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
64cfdbca75SSagar Srinivas                      stateSetId == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
65cfdbca75SSagar Srinivas             {
66cfdbca75SSagar Srinivas                 if (stateField[currState].effecter_state ==
67cfdbca75SSagar Srinivas                     uint8_t(CodeUpdateState::START))
68cfdbca75SSagar Srinivas                 {
69cfdbca75SSagar Srinivas                     codeUpdate->setCodeUpdateProgress(true);
703a0e3b9bSSampa Misra                     startUpdateEvent =
713a0e3b9bSSampa Misra                         std::make_unique<sdeventplus::source::Defer>(
723a0e3b9bSSampa Misra                             event,
733a0e3b9bSSampa Misra                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
743a0e3b9bSSampa Misra                                                       _processStartUpdate),
753a0e3b9bSSampa Misra                                       this, std::placeholders::_1));
76cfdbca75SSagar Srinivas                 }
77cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
78cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::END))
79cfdbca75SSagar Srinivas                 {
803a0e3b9bSSampa Misra                     rc = PLDM_SUCCESS;
813a0e3b9bSSampa Misra                     assembleImageEvent = std::make_unique<
823a0e3b9bSSampa Misra                         sdeventplus::source::Defer>(
833a0e3b9bSSampa Misra                         event,
843a0e3b9bSSampa Misra                         std::bind(
853a0e3b9bSSampa Misra                             std::mem_fn(
863a0e3b9bSSampa Misra                                 &oem_ibm_platform::Handler::_processEndUpdate),
873a0e3b9bSSampa Misra                             this, std::placeholders::_1));
883a0e3b9bSSampa Misra 
893a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, END, START);
90cfdbca75SSagar Srinivas                 }
91cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
92cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::ABORT))
93cfdbca75SSagar Srinivas                 {
94cfdbca75SSagar Srinivas                     codeUpdate->setCodeUpdateProgress(false);
95cfdbca75SSagar Srinivas                     codeUpdate->clearDirPath(LID_STAGING_DIR);
963a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
973a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
983a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::ABORT),
993a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::START));
1003a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, ABORT, END);
101cfdbca75SSagar Srinivas                 }
102cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
103cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::ACCEPT))
104cfdbca75SSagar Srinivas                 {
1053a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1063a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1073a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::ACCEPT),
1083a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::END));
109cfdbca75SSagar Srinivas                     // TODO Set new Dbus property provided by code update app
1103a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, ACCEPT, END);
111cfdbca75SSagar Srinivas                 }
112cfdbca75SSagar Srinivas                 else if (stateField[currState].effecter_state ==
113cfdbca75SSagar Srinivas                          uint8_t(CodeUpdateState::REJECT))
114cfdbca75SSagar Srinivas                 {
1153a0e3b9bSSampa Misra                     auto sensorId = codeUpdate->getFirmwareUpdateSensor();
1163a0e3b9bSSampa Misra                     sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
1173a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::REJECT),
1183a0e3b9bSSampa Misra                                          uint8_t(CodeUpdateState::END));
119cfdbca75SSagar Srinivas                     // TODO Set new Dbus property provided by code update app
1203a0e3b9bSSampa Misra                     // sendCodeUpdateEvent(effecterId, REJECT, END);
121cfdbca75SSagar Srinivas                 }
122cfdbca75SSagar Srinivas             }
123*9a64b4a7SSagar Srinivas             else if (entityType == PLDM_ENTITY_SYSTEM_CHASSIS &&
124*9a64b4a7SSagar Srinivas                      stateSetId == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
125*9a64b4a7SSagar Srinivas             {
126*9a64b4a7SSagar Srinivas                 if (stateField[currState].effecter_state == POWER_CYCLE_HARD)
127*9a64b4a7SSagar Srinivas                 {
128*9a64b4a7SSagar Srinivas                     systemRebootEvent =
129*9a64b4a7SSagar Srinivas                         std::make_unique<sdeventplus::source::Defer>(
130*9a64b4a7SSagar Srinivas                             event,
131*9a64b4a7SSagar Srinivas                             std::bind(std::mem_fn(&oem_ibm_platform::Handler::
132*9a64b4a7SSagar Srinivas                                                       _processSystemReboot),
133*9a64b4a7SSagar Srinivas                                       this, std::placeholders::_1));
134*9a64b4a7SSagar Srinivas                 }
135*9a64b4a7SSagar Srinivas             }
136aea5dde1SSampa Misra             else
137aea5dde1SSampa Misra             {
138aea5dde1SSampa Misra                 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
139aea5dde1SSampa Misra             }
140aea5dde1SSampa Misra         }
141aea5dde1SSampa Misra         if (rc != PLDM_SUCCESS)
142aea5dde1SSampa Misra         {
143aea5dde1SSampa Misra             break;
144aea5dde1SSampa Misra         }
145aea5dde1SSampa Misra     }
146aea5dde1SSampa Misra     return rc;
147aea5dde1SSampa Misra }
148aea5dde1SSampa Misra 
14978a225a2SSagar Srinivas void buildAllCodeUpdateEffecterPDR(platform::Handler* platformHandler,
150*9a64b4a7SSagar Srinivas                                    uint16_t entityType, uint16_t entityInstance,
151*9a64b4a7SSagar Srinivas                                    uint16_t stateSetID, pdr_utils::Repo& repo)
15278a225a2SSagar Srinivas {
15378a225a2SSagar Srinivas     size_t pdrSize = 0;
15478a225a2SSagar Srinivas     pdrSize = sizeof(pldm_state_effecter_pdr) +
15578a225a2SSagar Srinivas               sizeof(state_effecter_possible_states);
15678a225a2SSagar Srinivas     std::vector<uint8_t> entry{};
15778a225a2SSagar Srinivas     entry.resize(pdrSize);
15878a225a2SSagar Srinivas     pldm_state_effecter_pdr* pdr =
15978a225a2SSagar Srinivas         reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
16078a225a2SSagar Srinivas     if (!pdr)
16178a225a2SSagar Srinivas     {
16278a225a2SSagar Srinivas         std::cerr << "Failed to get record by PDR type, ERROR:"
16378a225a2SSagar Srinivas                   << PLDM_PLATFORM_INVALID_EFFECTER_ID << std::endl;
16478a225a2SSagar Srinivas     }
16578a225a2SSagar Srinivas     pdr->hdr.record_handle = 0;
16678a225a2SSagar Srinivas     pdr->hdr.version = 1;
16778a225a2SSagar Srinivas     pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
16878a225a2SSagar Srinivas     pdr->hdr.record_change_num = 0;
16978a225a2SSagar Srinivas     pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
17078a225a2SSagar Srinivas     pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
17178a225a2SSagar Srinivas     pdr->effecter_id = platformHandler->getNextEffecterId();
172*9a64b4a7SSagar Srinivas     pdr->entity_type = entityType;
17378a225a2SSagar Srinivas     pdr->entity_instance = entityInstance;
17478a225a2SSagar Srinivas     pdr->container_id = 0;
17578a225a2SSagar Srinivas     pdr->effecter_semantic_id = 0;
17678a225a2SSagar Srinivas     pdr->effecter_init = PLDM_NO_INIT;
17778a225a2SSagar Srinivas     pdr->has_description_pdr = false;
17878a225a2SSagar Srinivas     pdr->composite_effecter_count = 1;
17978a225a2SSagar Srinivas 
18078a225a2SSagar Srinivas     auto* possibleStatesPtr = pdr->possible_states;
18178a225a2SSagar Srinivas     auto possibleStates =
18278a225a2SSagar Srinivas         reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
18378a225a2SSagar Srinivas     possibleStates->state_set_id = stateSetID;
18478a225a2SSagar Srinivas     possibleStates->possible_states_size = 2;
18578a225a2SSagar Srinivas     auto state =
18678a225a2SSagar Srinivas         reinterpret_cast<state_effecter_possible_states*>(possibleStates);
18778a225a2SSagar Srinivas     if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
18878a225a2SSagar Srinivas         state->states[0].byte = 6;
18978a225a2SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
19078a225a2SSagar Srinivas         state->states[0].byte = 126;
191*9a64b4a7SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_SYSTEM_POWER_STATE)
192*9a64b4a7SSagar Srinivas         state->states[0].byte = 2;
19378a225a2SSagar Srinivas     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
19478a225a2SSagar Srinivas     pdrEntry.data = entry.data();
19578a225a2SSagar Srinivas     pdrEntry.size = pdrSize;
19678a225a2SSagar Srinivas     repo.addRecord(pdrEntry);
19778a225a2SSagar Srinivas }
19878a225a2SSagar Srinivas 
19978a225a2SSagar Srinivas void buildAllCodeUpdateSensorPDR(platform::Handler* platformHandler,
2003a0e3b9bSSampa Misra                                  uint16_t entityType, uint16_t entityInstance,
2013a0e3b9bSSampa Misra                                  uint16_t stateSetID, pdr_utils::Repo& repo)
20278a225a2SSagar Srinivas {
20378a225a2SSagar Srinivas     size_t pdrSize = 0;
20478a225a2SSagar Srinivas     pdrSize =
20578a225a2SSagar Srinivas         sizeof(pldm_state_sensor_pdr) + sizeof(state_sensor_possible_states);
20678a225a2SSagar Srinivas     std::vector<uint8_t> entry{};
20778a225a2SSagar Srinivas     entry.resize(pdrSize);
20878a225a2SSagar Srinivas     pldm_state_sensor_pdr* pdr =
20978a225a2SSagar Srinivas         reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
21078a225a2SSagar Srinivas     if (!pdr)
21178a225a2SSagar Srinivas     {
21278a225a2SSagar Srinivas         std::cerr << "Failed to get record by PDR type, ERROR:"
21378a225a2SSagar Srinivas                   << PLDM_PLATFORM_INVALID_SENSOR_ID << std::endl;
21478a225a2SSagar Srinivas     }
21578a225a2SSagar Srinivas     pdr->hdr.record_handle = 0;
21678a225a2SSagar Srinivas     pdr->hdr.version = 1;
21778a225a2SSagar Srinivas     pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
21878a225a2SSagar Srinivas     pdr->hdr.record_change_num = 0;
21978a225a2SSagar Srinivas     pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
22078a225a2SSagar Srinivas     pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
22178a225a2SSagar Srinivas     pdr->sensor_id = platformHandler->getNextSensorId();
2223a0e3b9bSSampa Misra     pdr->entity_type = entityType;
22378a225a2SSagar Srinivas     pdr->entity_instance = entityInstance;
22478a225a2SSagar Srinivas     pdr->container_id = 0;
22578a225a2SSagar Srinivas     pdr->sensor_init = PLDM_NO_INIT;
22678a225a2SSagar Srinivas     pdr->sensor_auxiliary_names_pdr = false;
22778a225a2SSagar Srinivas     pdr->composite_sensor_count = 1;
22878a225a2SSagar Srinivas 
22978a225a2SSagar Srinivas     auto* possibleStatesPtr = pdr->possible_states;
23078a225a2SSagar Srinivas     auto possibleStates =
23178a225a2SSagar Srinivas         reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
23278a225a2SSagar Srinivas     possibleStates->state_set_id = stateSetID;
23378a225a2SSagar Srinivas     possibleStates->possible_states_size = 2;
23478a225a2SSagar Srinivas     auto state =
23578a225a2SSagar Srinivas         reinterpret_cast<state_sensor_possible_states*>(possibleStates);
2363a0e3b9bSSampa Misra     if ((stateSetID == PLDM_OEM_IBM_BOOT_STATE) ||
2373a0e3b9bSSampa Misra         (stateSetID == oem_ibm_platform::PLDM_OEM_IBM_VERIFICATION_STATE))
23878a225a2SSagar Srinivas         state->states[0].byte = 6;
23978a225a2SSagar Srinivas     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
24078a225a2SSagar Srinivas         state->states[0].byte = 126;
24178a225a2SSagar Srinivas     pldm::responder::pdr_utils::PdrEntry pdrEntry{};
24278a225a2SSagar Srinivas     pdrEntry.data = entry.data();
24378a225a2SSagar Srinivas     pdrEntry.size = pdrSize;
24478a225a2SSagar Srinivas     repo.addRecord(pdrEntry);
24578a225a2SSagar Srinivas }
24678a225a2SSagar Srinivas 
24778a225a2SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
24878a225a2SSagar Srinivas     pdr_utils::Repo& repo)
24978a225a2SSagar Srinivas {
250*9a64b4a7SSagar Srinivas     buildAllCodeUpdateEffecterPDR(
251*9a64b4a7SSagar Srinivas         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
25278a225a2SSagar Srinivas         PLDM_OEM_IBM_BOOT_STATE, repo);
253*9a64b4a7SSagar Srinivas     buildAllCodeUpdateEffecterPDR(
254*9a64b4a7SSagar Srinivas         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_1,
25578a225a2SSagar Srinivas         PLDM_OEM_IBM_BOOT_STATE, repo);
256*9a64b4a7SSagar Srinivas     buildAllCodeUpdateEffecterPDR(
257*9a64b4a7SSagar Srinivas         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
25878a225a2SSagar Srinivas         PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
259*9a64b4a7SSagar Srinivas     buildAllCodeUpdateEffecterPDR(platformHandler, PLDM_ENTITY_SYSTEM_CHASSIS,
260*9a64b4a7SSagar Srinivas                                   ENTITY_INSTANCE_0,
261*9a64b4a7SSagar Srinivas                                   PLDM_OEM_IBM_SYSTEM_POWER_STATE, repo);
26278a225a2SSagar Srinivas 
2633a0e3b9bSSampa Misra     buildAllCodeUpdateSensorPDR(
2643a0e3b9bSSampa Misra         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
26578a225a2SSagar Srinivas         PLDM_OEM_IBM_BOOT_STATE, repo);
2663a0e3b9bSSampa Misra     buildAllCodeUpdateSensorPDR(
2673a0e3b9bSSampa Misra         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_1,
26878a225a2SSagar Srinivas         PLDM_OEM_IBM_BOOT_STATE, repo);
2693a0e3b9bSSampa Misra     buildAllCodeUpdateSensorPDR(
2703a0e3b9bSSampa Misra         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
27178a225a2SSagar Srinivas         PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
2723a0e3b9bSSampa Misra     buildAllCodeUpdateSensorPDR(
2733a0e3b9bSSampa Misra         platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
2743a0e3b9bSSampa Misra         PLDM_OEM_IBM_VERIFICATION_STATE, repo);
2753a0e3b9bSSampa Misra     auto sensorId = findStateSensorId(
2763a0e3b9bSSampa Misra         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2773a0e3b9bSSampa Misra         ENTITY_INSTANCE_0, 0, PLDM_OEM_IBM_VERIFICATION_STATE);
2783a0e3b9bSSampa Misra     codeUpdate->setMarkerLidSensor(sensorId);
2793a0e3b9bSSampa Misra     sensorId = findStateSensorId(
2803a0e3b9bSSampa Misra         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
2813a0e3b9bSSampa Misra         ENTITY_INSTANCE_0, 0, PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE);
2823a0e3b9bSSampa Misra     codeUpdate->setFirmwareUpdateSensor(sensorId);
28378a225a2SSagar Srinivas }
28478a225a2SSagar Srinivas 
285aea5dde1SSampa Misra void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
286aea5dde1SSampa Misra     pldm::responder::platform::Handler* handler)
287aea5dde1SSampa Misra {
288aea5dde1SSampa Misra     platformHandler = handler;
289aea5dde1SSampa Misra }
290aea5dde1SSampa Misra 
291bb585b28SVarsha Kaverappa int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
292bb585b28SVarsha Kaverappa     std::vector<uint8_t>& requestMsg)
293bb585b28SVarsha Kaverappa {
294bb585b28SVarsha Kaverappa     uint8_t* responseMsg = nullptr;
295bb585b28SVarsha Kaverappa     size_t responseMsgSize{};
296bb585b28SVarsha Kaverappa     if (requestMsg.size())
297bb585b28SVarsha Kaverappa     {
298bb585b28SVarsha Kaverappa         std::ostringstream tempStream;
299bb585b28SVarsha Kaverappa         for (int byte : requestMsg)
300bb585b28SVarsha Kaverappa         {
301bb585b28SVarsha Kaverappa             tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
302bb585b28SVarsha Kaverappa                        << " ";
303bb585b28SVarsha Kaverappa         }
304bb585b28SVarsha Kaverappa         std::cout << tempStream.str() << std::endl;
305bb585b28SVarsha Kaverappa     }
306bb585b28SVarsha Kaverappa 
307bb585b28SVarsha Kaverappa     auto requesterRc =
308bb585b28SVarsha Kaverappa         pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
309bb585b28SVarsha Kaverappa                        &responseMsg, &responseMsgSize);
310bb585b28SVarsha Kaverappa     std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
311bb585b28SVarsha Kaverappa                                                                   std::free};
312bb585b28SVarsha Kaverappa     if (requesterRc != PLDM_REQUESTER_SUCCESS)
313bb585b28SVarsha Kaverappa     {
314bb585b28SVarsha Kaverappa         std::cerr << "Failed to send message/receive response. RC = "
315bb585b28SVarsha Kaverappa                   << requesterRc << ", errno = " << errno
316bb585b28SVarsha Kaverappa                   << "for sending event to host \n";
317bb585b28SVarsha Kaverappa         return requesterRc;
318bb585b28SVarsha Kaverappa     }
319bb585b28SVarsha Kaverappa     uint8_t completionCode{};
320bb585b28SVarsha Kaverappa     uint8_t status{};
321bb585b28SVarsha Kaverappa     auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
322bb585b28SVarsha Kaverappa     auto rc = decode_platform_event_message_resp(
323bb585b28SVarsha Kaverappa         responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
324bb585b28SVarsha Kaverappa         &status);
325bb585b28SVarsha Kaverappa 
326bb585b28SVarsha Kaverappa     if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
327bb585b28SVarsha Kaverappa     {
328bb585b28SVarsha Kaverappa         std::cerr << "Failure in decode platform event message response, rc= "
329bb585b28SVarsha Kaverappa                   << rc << " cc=" << static_cast<unsigned>(completionCode)
330bb585b28SVarsha Kaverappa                   << "\n";
331bb585b28SVarsha Kaverappa         return rc;
332bb585b28SVarsha Kaverappa     }
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;
377bb585b28SVarsha Kaverappa         return;
378bb585b28SVarsha Kaverappa     }
379bb585b28SVarsha Kaverappa     rc = sendEventToHost(requestMsg);
380bb585b28SVarsha Kaverappa     if (rc != PLDM_SUCCESS)
381bb585b28SVarsha Kaverappa     {
382bb585b28SVarsha Kaverappa         std::cerr << "Failed to send event to host: "
383bb585b28SVarsha Kaverappa                   << "rc=" << rc << std::endl;
384bb585b28SVarsha Kaverappa     }
385bb585b28SVarsha Kaverappa     requester.markFree(mctp_eid, instanceId);
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();
3933a0e3b9bSSampa Misra     int retc = 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 
420*9a64b4a7SSagar Srinivas void pldm::responder::oem_ibm_platform::Handler::_processSystemReboot(
421*9a64b4a7SSagar Srinivas     sdeventplus::source::EventBase& /*source */)
422*9a64b4a7SSagar Srinivas {
423*9a64b4a7SSagar Srinivas     pldm::utils::PropertyValue value =
424*9a64b4a7SSagar Srinivas         "xyz.openbmc_project.State.Chassis.Transition.Off";
425*9a64b4a7SSagar Srinivas     pldm::utils::DBusMapping dbusMapping{"/xyz/openbmc_project/state/chassis0",
426*9a64b4a7SSagar Srinivas                                          "xyz.openbmc_project.State.Chassis",
427*9a64b4a7SSagar Srinivas                                          "RequestedPowerTransition", "string"};
428*9a64b4a7SSagar Srinivas     try
429*9a64b4a7SSagar Srinivas     {
430*9a64b4a7SSagar Srinivas         dBusIntf->setDbusProperty(dbusMapping, value);
431*9a64b4a7SSagar Srinivas     }
432*9a64b4a7SSagar Srinivas     catch (const std::exception& e)
433*9a64b4a7SSagar Srinivas     {
434*9a64b4a7SSagar Srinivas 
435*9a64b4a7SSagar Srinivas         std::cerr << "Chassis State transition to Off failed,"
436*9a64b4a7SSagar Srinivas                   << "unable to set property RequestedPowerTransition"
437*9a64b4a7SSagar Srinivas                   << "ERROR=" << e.what() << "\n";
438*9a64b4a7SSagar Srinivas     }
439*9a64b4a7SSagar Srinivas 
440*9a64b4a7SSagar Srinivas     using namespace sdbusplus::bus::match::rules;
441*9a64b4a7SSagar Srinivas     chassisOffMatch = std::make_unique<sdbusplus::bus::match::match>(
442*9a64b4a7SSagar Srinivas         pldm::utils::DBusHandler::getBus(),
443*9a64b4a7SSagar Srinivas         propertiesChanged("/xyz/openbmc_project/state/chassis0",
444*9a64b4a7SSagar Srinivas                           "xyz.openbmc_project.State.Chassis"),
445*9a64b4a7SSagar Srinivas         [this](sdbusplus::message::message& msg) {
446*9a64b4a7SSagar Srinivas             DbusChangedProps props{};
447*9a64b4a7SSagar Srinivas             std::string intf;
448*9a64b4a7SSagar Srinivas             msg.read(intf, props);
449*9a64b4a7SSagar Srinivas             const auto itr = props.find("CurrentPowerState");
450*9a64b4a7SSagar Srinivas             if (itr != props.end())
451*9a64b4a7SSagar Srinivas             {
452*9a64b4a7SSagar Srinivas                 PropertyValue value = itr->second;
453*9a64b4a7SSagar Srinivas                 auto propVal = std::get<std::string>(value);
454*9a64b4a7SSagar Srinivas                 if (propVal ==
455*9a64b4a7SSagar Srinivas                     "xyz.openbmc_project.State.Chassis.PowerState.Off")
456*9a64b4a7SSagar Srinivas                 {
457*9a64b4a7SSagar Srinivas                     pldm::utils::DBusMapping dbusMapping{
458*9a64b4a7SSagar Srinivas                         "/xyz/openbmc_project/control/host0/"
459*9a64b4a7SSagar Srinivas                         "power_restore_policy/one_time",
460*9a64b4a7SSagar Srinivas                         "xyz.openbmc_project.Control.Power.RestorePolicy",
461*9a64b4a7SSagar Srinivas                         "PowerRestorePolicy", "string"};
462*9a64b4a7SSagar Srinivas                     value = "xyz.openbmc_project.Control.Power.RestorePolicy."
463*9a64b4a7SSagar Srinivas                             "Policy.AlwaysOn";
464*9a64b4a7SSagar Srinivas                     try
465*9a64b4a7SSagar Srinivas                     {
466*9a64b4a7SSagar Srinivas                         dBusIntf->setDbusProperty(dbusMapping, value);
467*9a64b4a7SSagar Srinivas                     }
468*9a64b4a7SSagar Srinivas                     catch (const std::exception& e)
469*9a64b4a7SSagar Srinivas                     {
470*9a64b4a7SSagar Srinivas                         std::cerr << "Setting one-time restore policy failed,"
471*9a64b4a7SSagar Srinivas                                   << "unable to set property PowerRestorePolicy"
472*9a64b4a7SSagar Srinivas                                   << "ERROR=" << e.what() << "\n";
473*9a64b4a7SSagar Srinivas                     }
474*9a64b4a7SSagar Srinivas                     dbusMapping = pldm::utils::DBusMapping{
475*9a64b4a7SSagar Srinivas                         "/xyz/openbmc_project/state/bmc0",
476*9a64b4a7SSagar Srinivas                         "xyz.openbmc_project.State.BMC",
477*9a64b4a7SSagar Srinivas                         "RequestedBMCTransition", "string"};
478*9a64b4a7SSagar Srinivas                     value = "xyz.openbmc_project.State.BMC.Transition.Reboot";
479*9a64b4a7SSagar Srinivas                     try
480*9a64b4a7SSagar Srinivas                     {
481*9a64b4a7SSagar Srinivas                         dBusIntf->setDbusProperty(dbusMapping, value);
482*9a64b4a7SSagar Srinivas                     }
483*9a64b4a7SSagar Srinivas                     catch (const std::exception& e)
484*9a64b4a7SSagar Srinivas                     {
485*9a64b4a7SSagar Srinivas                         std::cerr << "BMC state transition to reboot failed,"
486*9a64b4a7SSagar Srinivas                                   << "unable to set property "
487*9a64b4a7SSagar Srinivas                                      "RequestedBMCTransition"
488*9a64b4a7SSagar Srinivas                                   << "ERROR=" << e.what() << "\n";
489*9a64b4a7SSagar Srinivas                     }
490*9a64b4a7SSagar Srinivas                 }
491*9a64b4a7SSagar Srinivas             }
492*9a64b4a7SSagar Srinivas         });
493*9a64b4a7SSagar Srinivas }
494aea5dde1SSampa Misra } // namespace oem_ibm_platform
495aea5dde1SSampa Misra } // namespace responder
496aea5dde1SSampa Misra } // namespace pldm
497