xref: /openbmc/openpower-occ-control/pldm.cpp (revision cbad219e)
1815f9f55STom Joseph #include "pldm.hpp"
2815f9f55STom Joseph 
300325238STom Joseph #include "file.hpp"
400325238STom Joseph 
5a8857c50SChris Cain #include <fmt/core.h>
6815f9f55STom Joseph #include <libpldm/entity.h>
7815f9f55STom Joseph #include <libpldm/platform.h>
8815f9f55STom Joseph #include <libpldm/state_set.h>
9815f9f55STom Joseph 
10815f9f55STom Joseph #include <phosphor-logging/log.hpp>
11815f9f55STom Joseph 
12*cbad219eSEddie James #define PLDM_OEM_IBM_SBE_MAINTENANCE_STATE 32772
13*cbad219eSEddie James #define SBE_RETRY_REQUIRED 0x2
14*cbad219eSEddie James 
15*cbad219eSEddie James #define PLDM_OEM_IBM_SBE_HRESET_STATE 32775
16*cbad219eSEddie James #define SBE_HRESET_NOT_READY 0x1
17*cbad219eSEddie James #define SBE_HRESET_READY 0x2
18*cbad219eSEddie James #define SBE_HRESET_FAILED 0x3
19*cbad219eSEddie James 
20815f9f55STom Joseph namespace pldm
21815f9f55STom Joseph {
22815f9f55STom Joseph 
23815f9f55STom Joseph using namespace phosphor::logging;
24815f9f55STom Joseph 
25*cbad219eSEddie James void Interface::fetchSensorInfo(uint16_t stateSetId,
26*cbad219eSEddie James                                 SensorToInstance& sensorInstanceMap,
27815f9f55STom Joseph                                 SensorOffset& sensorOffset)
28815f9f55STom Joseph {
29*cbad219eSEddie James     PdrList pdrs{};
30*cbad219eSEddie James 
31*cbad219eSEddie James     auto& bus = open_power::occ::utils::getBus();
32*cbad219eSEddie James     try
33*cbad219eSEddie James     {
34*cbad219eSEddie James         auto method = bus.new_method_call(
35*cbad219eSEddie James             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
36*cbad219eSEddie James             "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
37*cbad219eSEddie James         method.append(tid, (uint16_t)PLDM_ENTITY_PROC, stateSetId);
38*cbad219eSEddie James 
39*cbad219eSEddie James         auto responseMsg = bus.call(method);
40*cbad219eSEddie James         responseMsg.read(pdrs);
41*cbad219eSEddie James     }
42*cbad219eSEddie James     catch (const sdbusplus::exception::exception& e)
43*cbad219eSEddie James     {
44*cbad219eSEddie James         log<level::ERR>("pldm: Failed to fetch the state sensor PDRs",
45*cbad219eSEddie James                         entry("ERROR=%s", e.what()));
46*cbad219eSEddie James     }
47*cbad219eSEddie James 
48*cbad219eSEddie James     if (pdrs.empty())
49*cbad219eSEddie James     {
50*cbad219eSEddie James         log<level::ERR>("pldm: state sensor PDRs not present");
51*cbad219eSEddie James         return;
52*cbad219eSEddie James     }
53*cbad219eSEddie James 
54815f9f55STom Joseph     bool offsetFound = false;
55815f9f55STom Joseph     auto pdr =
56815f9f55STom Joseph         reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
57815f9f55STom Joseph     auto possibleStatesPtr = pdr->possible_states;
58815f9f55STom Joseph     for (auto offset = 0; offset < pdr->composite_sensor_count; offset++)
59815f9f55STom Joseph     {
60815f9f55STom Joseph         auto possibleStates =
61815f9f55STom Joseph             reinterpret_cast<const state_sensor_possible_states*>(
62815f9f55STom Joseph                 possibleStatesPtr);
63815f9f55STom Joseph 
64*cbad219eSEddie James         if (possibleStates->state_set_id == stateSetId)
65815f9f55STom Joseph         {
66815f9f55STom Joseph             sensorOffset = offset;
67815f9f55STom Joseph             offsetFound = true;
68815f9f55STom Joseph             break;
69815f9f55STom Joseph         }
70815f9f55STom Joseph         possibleStatesPtr += sizeof(possibleStates->state_set_id) +
71815f9f55STom Joseph                              sizeof(possibleStates->possible_states_size) +
72815f9f55STom Joseph                              possibleStates->possible_states_size;
73815f9f55STom Joseph     }
74815f9f55STom Joseph 
75815f9f55STom Joseph     if (!offsetFound)
76815f9f55STom Joseph     {
77*cbad219eSEddie James         log<level::ERR>("pldm: state sensor PDR not found");
78815f9f55STom Joseph         return;
79815f9f55STom Joseph     }
80815f9f55STom Joseph 
811339ab60SMatt Spinler     // To order SensorID based on the EntityInstance.
821339ab60SMatt Spinler     // Note that when a proc is on a DCM, the PDRs for these sensors
831339ab60SMatt Spinler     // could have the same instance IDs but different container IDs.
841339ab60SMatt Spinler     std::map<uint32_t, SensorID> entityInstMap{};
85815f9f55STom Joseph     for (auto& pdr : pdrs)
86815f9f55STom Joseph     {
87815f9f55STom Joseph         auto pdrPtr =
88815f9f55STom Joseph             reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
891339ab60SMatt Spinler         uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
901339ab60SMatt Spinler                        static_cast<uint32_t>(pdrPtr->entity_instance);
911339ab60SMatt Spinler         entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->sensor_id));
92815f9f55STom Joseph     }
93815f9f55STom Joseph 
94815f9f55STom Joseph     open_power::occ::instanceID count = start;
95815f9f55STom Joseph     for (auto const& pair : entityInstMap)
96815f9f55STom Joseph     {
97815f9f55STom Joseph         sensorInstanceMap.emplace(pair.second, count);
98815f9f55STom Joseph         count++;
99815f9f55STom Joseph     }
100815f9f55STom Joseph }
101815f9f55STom Joseph 
102815f9f55STom Joseph void Interface::sensorEvent(sdbusplus::message::message& msg)
103815f9f55STom Joseph {
104815f9f55STom Joseph     if (!isOCCSensorCacheValid())
105815f9f55STom Joseph     {
106*cbad219eSEddie James         fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
107*cbad219eSEddie James                         sensorToOCCInstance, OCCSensorOffset);
108815f9f55STom Joseph     }
109815f9f55STom Joseph 
110*cbad219eSEddie James     if (sensorToSBEInstance.empty())
111815f9f55STom Joseph     {
112*cbad219eSEddie James         fetchSensorInfo(PLDM_OEM_IBM_SBE_HRESET_STATE, sensorToSBEInstance,
113*cbad219eSEddie James                         SBESensorOffset);
114815f9f55STom Joseph     }
115815f9f55STom Joseph 
116815f9f55STom Joseph     TerminusID tid{};
117815f9f55STom Joseph     SensorID sensorId{};
118815f9f55STom Joseph     SensorOffset msgSensorOffset{};
119815f9f55STom Joseph     EventState eventState{};
120815f9f55STom Joseph     EventState previousEventState{};
121815f9f55STom Joseph 
122a17f6e8cSGeorge Liu     msg.read(tid, sensorId, msgSensorOffset, eventState, previousEventState);
123815f9f55STom Joseph 
124*cbad219eSEddie James     if (msgSensorOffset == OCCSensorOffset)
125815f9f55STom Joseph     {
126*cbad219eSEddie James         auto sensorEntry = sensorToOCCInstance.find(sensorId);
127*cbad219eSEddie James 
128*cbad219eSEddie James         if (sensorEntry == sensorToOCCInstance.end())
129*cbad219eSEddie James         {
130815f9f55STom Joseph             return;
131815f9f55STom Joseph         }
132815f9f55STom Joseph 
133*cbad219eSEddie James         if (eventState ==
134*cbad219eSEddie James             static_cast<EventState>(
135815f9f55STom Joseph                 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
136815f9f55STom Joseph         {
137a8857c50SChris Cain             log<level::INFO>(
138*cbad219eSEddie James                 fmt::format("PLDM: OCC{} is RUNNING", sensorEntry->second)
139*cbad219eSEddie James                     .c_str());
140a8857c50SChris Cain             callBack(sensorEntry->second, true);
141815f9f55STom Joseph         }
142815f9f55STom Joseph         else if (eventState ==
143815f9f55STom Joseph                  static_cast<EventState>(
144815f9f55STom Joseph                      PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
145815f9f55STom Joseph         {
146a8857c50SChris Cain             log<level::INFO>(
147a8857c50SChris Cain                 fmt::format("PLDM: OCC{} has now STOPPED", sensorEntry->second)
148a8857c50SChris Cain                     .c_str());
149a8857c50SChris Cain             callBack(sensorEntry->second, false);
150815f9f55STom Joseph         }
151*cbad219eSEddie James     }
152*cbad219eSEddie James     else if (msgSensorOffset == SBESensorOffset)
153*cbad219eSEddie James     {
154*cbad219eSEddie James         auto sensorEntry = sensorToSBEInstance.find(sensorId);
155815f9f55STom Joseph 
156*cbad219eSEddie James         if (sensorEntry == sensorToSBEInstance.end())
157*cbad219eSEddie James         {
158815f9f55STom Joseph             return;
159815f9f55STom Joseph         }
160815f9f55STom Joseph 
161*cbad219eSEddie James         if (eventState == static_cast<EventState>(SBE_HRESET_NOT_READY))
162*cbad219eSEddie James         {
163*cbad219eSEddie James             log<level::INFO>("pldm: HRESET is NOT READY",
164*cbad219eSEddie James                              entry("SBE=%d", sensorEntry->second));
165*cbad219eSEddie James         }
166*cbad219eSEddie James         else if (eventState == static_cast<EventState>(SBE_HRESET_READY))
167*cbad219eSEddie James         {
168*cbad219eSEddie James             sbeCallBack(sensorEntry->second, true);
169*cbad219eSEddie James         }
170*cbad219eSEddie James         else if (eventState == static_cast<EventState>(SBE_HRESET_FAILED))
171*cbad219eSEddie James         {
172*cbad219eSEddie James             sbeCallBack(sensorEntry->second, false);
173*cbad219eSEddie James         }
174*cbad219eSEddie James     }
175*cbad219eSEddie James }
176*cbad219eSEddie James 
177815f9f55STom Joseph void Interface::hostStateEvent(sdbusplus::message::message& msg)
178815f9f55STom Joseph {
179815f9f55STom Joseph     std::map<std::string, std::variant<std::string>> properties{};
180815f9f55STom Joseph     std::string interface;
181815f9f55STom Joseph     msg.read(interface, properties);
182815f9f55STom Joseph     const auto stateEntry = properties.find("CurrentHostState");
183815f9f55STom Joseph     if (stateEntry != properties.end())
184815f9f55STom Joseph     {
185815f9f55STom Joseph         auto stateEntryValue = stateEntry->second;
186815f9f55STom Joseph         auto propVal = std::get<std::string>(stateEntryValue);
187815f9f55STom Joseph         if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
188815f9f55STom Joseph         {
189815f9f55STom Joseph             sensorToOCCInstance.clear();
19000325238STom Joseph             occInstanceToEffecter.clear();
191*cbad219eSEddie James 
192*cbad219eSEddie James             sensorToSBEInstance.clear();
193*cbad219eSEddie James             sbeInstanceToEffecter.clear();
194815f9f55STom Joseph         }
195815f9f55STom Joseph     }
196815f9f55STom Joseph }
197815f9f55STom Joseph 
198*cbad219eSEddie James void Interface::fetchEffecterInfo(uint16_t entityId, uint16_t stateSetId,
199*cbad219eSEddie James                                   InstanceToEffecter& instanceToEffecterMap,
200*cbad219eSEddie James                                   CompositeEffecterCount& effecterCount,
201*cbad219eSEddie James                                   uint8_t& stateIdPos)
20200325238STom Joseph {
203*cbad219eSEddie James     PdrList pdrs{};
204*cbad219eSEddie James 
205*cbad219eSEddie James     auto& bus = open_power::occ::utils::getBus();
206*cbad219eSEddie James     try
207*cbad219eSEddie James     {
208*cbad219eSEddie James         auto method = bus.new_method_call(
209*cbad219eSEddie James             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
210*cbad219eSEddie James             "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
211*cbad219eSEddie James         method.append(tid, entityId, stateSetId);
212*cbad219eSEddie James 
213*cbad219eSEddie James         auto responseMsg = bus.call(method);
214*cbad219eSEddie James         responseMsg.read(pdrs);
215*cbad219eSEddie James     }
216*cbad219eSEddie James     catch (const sdbusplus::exception::exception& e)
217*cbad219eSEddie James     {
218*cbad219eSEddie James         log<level::ERR>("pldm: Failed to fetch the state effecter PDRs",
219*cbad219eSEddie James                         entry("ERROR=%s", e.what()));
220*cbad219eSEddie James     }
221*cbad219eSEddie James 
222*cbad219eSEddie James     if (!pdrs.size())
223*cbad219eSEddie James     {
224*cbad219eSEddie James         log<level::ERR>("pldm: state effecter PDRs not present");
225*cbad219eSEddie James         return;
226*cbad219eSEddie James     }
227*cbad219eSEddie James 
22800325238STom Joseph     bool offsetFound = false;
22900325238STom Joseph     auto pdr =
23000325238STom Joseph         reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
23100325238STom Joseph     auto possibleStatesPtr = pdr->possible_states;
23200325238STom Joseph     for (auto offset = 0; offset < pdr->composite_effecter_count; offset++)
23300325238STom Joseph     {
23400325238STom Joseph         auto possibleStates =
23500325238STom Joseph             reinterpret_cast<const state_effecter_possible_states*>(
23600325238STom Joseph                 possibleStatesPtr);
23700325238STom Joseph 
238*cbad219eSEddie James         if (possibleStates->state_set_id == stateSetId)
23900325238STom Joseph         {
240*cbad219eSEddie James             stateIdPos = offset;
24100325238STom Joseph             effecterCount = pdr->composite_effecter_count;
24200325238STom Joseph             offsetFound = true;
24300325238STom Joseph             break;
24400325238STom Joseph         }
24500325238STom Joseph         possibleStatesPtr += sizeof(possibleStates->state_set_id) +
24600325238STom Joseph                              sizeof(possibleStates->possible_states_size) +
24700325238STom Joseph                              possibleStates->possible_states_size;
24800325238STom Joseph     }
24900325238STom Joseph 
25000325238STom Joseph     if (!offsetFound)
25100325238STom Joseph     {
25200325238STom Joseph         return;
25300325238STom Joseph     }
25400325238STom Joseph 
25500325238STom Joseph     std::map<EntityInstance, EffecterID> entityInstMap{};
25600325238STom Joseph     for (auto& pdr : pdrs)
25700325238STom Joseph     {
25800325238STom Joseph         auto pdrPtr =
25900325238STom Joseph             reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
2601339ab60SMatt Spinler         uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
2611339ab60SMatt Spinler                        static_cast<uint32_t>(pdrPtr->entity_instance);
2621339ab60SMatt Spinler         entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->effecter_id));
26300325238STom Joseph     }
26400325238STom Joseph 
26500325238STom Joseph     open_power::occ::instanceID position = start;
26600325238STom Joseph     for (auto const& pair : entityInstMap)
26700325238STom Joseph     {
268*cbad219eSEddie James         instanceToEffecterMap.emplace(position, pair.second);
26900325238STom Joseph         position++;
27000325238STom Joseph     }
27100325238STom Joseph }
27200325238STom Joseph 
27300325238STom Joseph std::vector<uint8_t>
27400325238STom Joseph     Interface::prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
27500325238STom Joseph                                      CompositeEffecterCount effecterCount,
276*cbad219eSEddie James                                      uint8_t stateIdPos, uint8_t stateSetValue)
27700325238STom Joseph {
27800325238STom Joseph     std::vector<uint8_t> request(
27900325238STom Joseph         sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
28000325238STom Joseph         (effecterCount * sizeof(set_effecter_state_field)));
28100325238STom Joseph     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
28200325238STom Joseph     std::vector<set_effecter_state_field> stateField;
28300325238STom Joseph 
28400325238STom Joseph     for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
28500325238STom Joseph     {
286*cbad219eSEddie James         if (effecterPos == stateIdPos)
28700325238STom Joseph         {
288*cbad219eSEddie James             stateField.emplace_back(
289*cbad219eSEddie James                 set_effecter_state_field{PLDM_REQUEST_SET, stateSetValue});
29000325238STom Joseph         }
29100325238STom Joseph         else
29200325238STom Joseph         {
29300325238STom Joseph             stateField.emplace_back(
29400325238STom Joseph                 set_effecter_state_field{PLDM_NO_CHANGE, 0});
29500325238STom Joseph         }
29600325238STom Joseph     }
29700325238STom Joseph     auto rc = encode_set_state_effecter_states_req(
29800325238STom Joseph         instanceId, effecterId, effecterCount, stateField.data(), requestMsg);
29900325238STom Joseph     if (rc != PLDM_SUCCESS)
30000325238STom Joseph     {
30100325238STom Joseph         log<level::ERR>("encode set effecter states request returned error ",
30200325238STom Joseph                         entry("RC=%d", rc));
30300325238STom Joseph         request.clear();
30400325238STom Joseph     }
30500325238STom Joseph     return request;
30600325238STom Joseph }
30700325238STom Joseph 
30800325238STom Joseph void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
30900325238STom Joseph {
31000325238STom Joseph     if (!isPDREffecterCacheValid())
31100325238STom Joseph     {
312*cbad219eSEddie James         fetchEffecterInfo(
313*cbad219eSEddie James             PLDM_ENTITY_PROC_MODULE, PLDM_STATE_SET_BOOT_RESTART_CAUSE,
314*cbad219eSEddie James             occInstanceToEffecter, OCCEffecterCount, bootRestartPosition);
31500325238STom Joseph     }
31600325238STom Joseph 
31700325238STom Joseph     // Find the matching effecter for the OCC instance
31800325238STom Joseph     auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
31900325238STom Joseph     if (effecterEntry == occInstanceToEffecter.end())
32000325238STom Joseph     {
32100325238STom Joseph         log<level::ERR>(
32200325238STom Joseph             "pldm: Failed to find a matching effecter for OCC instance",
32300325238STom Joseph             entry("OCC_INSTANCE_ID=%d", occInstanceId));
32400325238STom Joseph 
32500325238STom Joseph         return;
32600325238STom Joseph     }
32700325238STom Joseph 
32800325238STom Joseph     uint8_t instanceId{};
329*cbad219eSEddie James     if (!getMctpInstanceId(instanceId))
330*cbad219eSEddie James     {
331*cbad219eSEddie James         return;
332*cbad219eSEddie James     }
33300325238STom Joseph 
334*cbad219eSEddie James     // Prepare the SetStateEffecterStates request to reset the OCC
335*cbad219eSEddie James     auto request = prepareSetEffecterReq(
336*cbad219eSEddie James         instanceId, effecterEntry->second, OCCEffecterCount,
337*cbad219eSEddie James         bootRestartPosition, PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET);
338*cbad219eSEddie James 
339*cbad219eSEddie James     if (request.empty())
340*cbad219eSEddie James     {
341*cbad219eSEddie James         log<level::ERR>("pldm: SetStateEffecterStates OCC reset request empty");
342*cbad219eSEddie James         return;
343*cbad219eSEddie James     }
344*cbad219eSEddie James 
345*cbad219eSEddie James     sendPldm(request);
346*cbad219eSEddie James }
347*cbad219eSEddie James 
348*cbad219eSEddie James void Interface::sendHRESET(open_power::occ::instanceID sbeInstanceId)
349*cbad219eSEddie James {
350*cbad219eSEddie James     if (sbeInstanceToEffecter.empty())
351*cbad219eSEddie James     {
352*cbad219eSEddie James         fetchEffecterInfo(PLDM_ENTITY_PROC, PLDM_OEM_IBM_SBE_MAINTENANCE_STATE,
353*cbad219eSEddie James                           sbeInstanceToEffecter, SBEEffecterCount,
354*cbad219eSEddie James                           sbeMaintenanceStatePosition);
355*cbad219eSEddie James     }
356*cbad219eSEddie James 
357*cbad219eSEddie James     auto effecterEntry = sbeInstanceToEffecter.find(sbeInstanceId);
358*cbad219eSEddie James     if (effecterEntry == sbeInstanceToEffecter.end())
359*cbad219eSEddie James     {
360*cbad219eSEddie James         log<level::ERR>(
361*cbad219eSEddie James             "pldm: Failed to find a matching effecter for SBE instance",
362*cbad219eSEddie James             entry("SBE=%d", sbeInstanceId));
363*cbad219eSEddie James         return;
364*cbad219eSEddie James     }
365*cbad219eSEddie James 
366*cbad219eSEddie James     uint8_t instanceId{};
367*cbad219eSEddie James     if (!getMctpInstanceId(instanceId))
368*cbad219eSEddie James     {
369*cbad219eSEddie James         return;
370*cbad219eSEddie James     }
371*cbad219eSEddie James 
372*cbad219eSEddie James     // Prepare the SetStateEffecterStates request to HRESET the SBE
373*cbad219eSEddie James     auto request = prepareSetEffecterReq(
374*cbad219eSEddie James         instanceId, effecterEntry->second, SBEEffecterCount,
375*cbad219eSEddie James         sbeMaintenanceStatePosition, SBE_RETRY_REQUIRED);
376*cbad219eSEddie James 
377*cbad219eSEddie James     if (request.empty())
378*cbad219eSEddie James     {
379*cbad219eSEddie James         log<level::ERR>("pldm: SetStateEffecterStates HRESET request empty");
380*cbad219eSEddie James         return;
381*cbad219eSEddie James     }
382*cbad219eSEddie James 
383*cbad219eSEddie James     sendPldm(request);
384*cbad219eSEddie James }
385*cbad219eSEddie James 
386*cbad219eSEddie James bool Interface::getMctpInstanceId(uint8_t& instanceId)
387*cbad219eSEddie James {
38848330578SChris Cain     auto& bus = open_power::occ::utils::getBus();
38900325238STom Joseph     try
39000325238STom Joseph     {
39100325238STom Joseph         auto method = bus.new_method_call(
39200325238STom Joseph             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
39300325238STom Joseph             "xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
39400325238STom Joseph         method.append(mctpEid);
39500325238STom Joseph         auto reply = bus.call(method);
39600325238STom Joseph         reply.read(instanceId);
39700325238STom Joseph     }
39825613624SPatrick Williams     catch (const sdbusplus::exception::exception& e)
39900325238STom Joseph     {
40000325238STom Joseph         log<level::ERR>("pldm: GetInstanceId returned error",
40100325238STom Joseph                         entry("ERROR=%s", e.what()));
402*cbad219eSEddie James         return false;
40300325238STom Joseph     }
40400325238STom Joseph 
405*cbad219eSEddie James     return true;
406*cbad219eSEddie James }
40700325238STom Joseph 
408*cbad219eSEddie James void Interface::sendPldm(const std::vector<uint8_t>& request)
40900325238STom Joseph {
41000325238STom Joseph     // Connect to MCTP scoket
41100325238STom Joseph     int fd = pldm_open();
41200325238STom Joseph     if (fd == -1)
41300325238STom Joseph     {
41400325238STom Joseph         log<level::ERR>("pldm: Failed to connect to MCTP socket");
41500325238STom Joseph         return;
41600325238STom Joseph     }
417*cbad219eSEddie James 
41800325238STom Joseph     open_power::occ::FileDescriptor fileFd(fd);
41900325238STom Joseph 
42000325238STom Joseph     // Send the PLDM request message to HBRT
42100325238STom Joseph     uint8_t* response = nullptr;
42200325238STom Joseph     size_t responseSize{};
42300325238STom Joseph     auto rc = pldm_send_recv(mctpEid, fileFd(), request.data(), request.size(),
42400325238STom Joseph                              &response, &responseSize);
42500325238STom Joseph     std::unique_ptr<uint8_t, decltype(std::free)*> responsePtr{response,
42600325238STom Joseph                                                                std::free};
42700325238STom Joseph     if (rc)
42800325238STom Joseph     {
429*cbad219eSEddie James         log<level::ERR>("pldm: pldm_send_recv failed", entry("RC=%d", rc));
43000325238STom Joseph     }
43100325238STom Joseph 
43200325238STom Joseph     uint8_t completionCode{};
43300325238STom Joseph     auto responseMsg = reinterpret_cast<const pldm_msg*>(responsePtr.get());
43400325238STom Joseph     auto rcDecode = decode_set_state_effecter_states_resp(
43500325238STom Joseph         responseMsg, responseSize - sizeof(pldm_msg_hdr), &completionCode);
43600325238STom Joseph     if (rcDecode || completionCode)
43700325238STom Joseph     {
43800325238STom Joseph         log<level::ERR>(
43900325238STom Joseph             "pldm: decode_set_state_effecter_states_resp returned error",
44000325238STom Joseph             entry("RC=%d", rcDecode),
44100325238STom Joseph             entry("COMPLETION_CODE=%d", completionCode));
44200325238STom Joseph     }
44300325238STom Joseph }
44400325238STom Joseph 
445815f9f55STom Joseph } // namespace pldm
446