xref: /openbmc/openpower-occ-control/pldm.cpp (revision c488bac124fbbcb0dbe83e48922c3087a5aaa7bd)
1815f9f55STom Joseph #include "pldm.hpp"
2815f9f55STom Joseph 
3db38e91aSRashmica Gupta #include "libpldm/instance-id.h"
4db38e91aSRashmica Gupta 
500325238STom Joseph #include "file.hpp"
600325238STom Joseph 
7815f9f55STom Joseph #include <libpldm/entity.h>
897476a1eSAndrew Jeffery #include <libpldm/oem/ibm/state_set.h>
9815f9f55STom Joseph #include <libpldm/platform.h>
10815f9f55STom Joseph #include <libpldm/state_set.h>
1152328cb4SRashmica Gupta #include <libpldm/transport.h>
126213f199SLakshmi Yadlapati #include <libpldm/transport/af-mctp.h>
1352328cb4SRashmica Gupta #include <libpldm/transport/mctp-demux.h>
1452328cb4SRashmica Gupta #include <poll.h>
15815f9f55STom Joseph 
1637abe9beSChris Cain #include <phosphor-logging/lg2.hpp>
17bae4d07eSChris Cain #include <sdbusplus/bus.hpp>
18bae4d07eSChris Cain #include <sdeventplus/clock.hpp>
19bae4d07eSChris Cain #include <sdeventplus/exception.hpp>
20bae4d07eSChris Cain #include <sdeventplus/source/io.hpp>
21bae4d07eSChris Cain #include <sdeventplus/source/time.hpp>
22bae4d07eSChris Cain 
23bae4d07eSChris Cain #include <algorithm>
24815f9f55STom Joseph 
25815f9f55STom Joseph namespace pldm
26815f9f55STom Joseph {
27815f9f55STom Joseph 
28bae4d07eSChris Cain using namespace sdeventplus;
29bae4d07eSChris Cain using namespace sdeventplus::source;
30bae4d07eSChris Cain constexpr auto clockId = sdeventplus::ClockId::RealTime;
31bae4d07eSChris Cain using Clock = sdeventplus::Clock<clockId>;
32bae4d07eSChris Cain using Timer = Time<clockId>;
33755af102SChris Cain bool Interface::throttleTraces = false;
34f0295f52SChris Cain enum pldm_msg_type Interface::msgType = MSG_UNDEFINED;
35f0295f52SChris Cain open_power::occ::instanceID Interface::resetInstance = 0;
36bae4d07eSChris Cain 
fetchSensorInfo(uint16_t stateSetId,SensorToInstance & sensorInstanceMap,SensorOffset & sensorOffset)37cbad219eSEddie James void Interface::fetchSensorInfo(uint16_t stateSetId,
38cbad219eSEddie James                                 SensorToInstance& sensorInstanceMap,
39815f9f55STom Joseph                                 SensorOffset& sensorOffset)
40815f9f55STom Joseph {
41cbad219eSEddie James     PdrList pdrs{};
42bae4d07eSChris Cain     static bool tracedError = false;
43cbad219eSEddie James 
44cbad219eSEddie James     auto& bus = open_power::occ::utils::getBus();
45cbad219eSEddie James     try
46cbad219eSEddie James     {
47cbad219eSEddie James         auto method = bus.new_method_call(
48cbad219eSEddie James             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
49cbad219eSEddie James             "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
50bae4d07eSChris Cain         method.append(tid, static_cast<uint16_t>(PLDM_ENTITY_PROC), stateSetId);
51cbad219eSEddie James 
52cbad219eSEddie James         auto responseMsg = bus.call(method);
53cbad219eSEddie James         responseMsg.read(pdrs);
54cbad219eSEddie James     }
55af40808fSPatrick Williams     catch (const sdbusplus::exception_t& e)
56cbad219eSEddie James     {
57bae4d07eSChris Cain         if (!tracedError)
58bae4d07eSChris Cain         {
5937abe9beSChris Cain             lg2::error(
6037abe9beSChris Cain                 "fetchSensorInfo: Failed to find stateSetID:{ID} PDR: {ERR}",
6137abe9beSChris Cain                 "ID", stateSetId, "ERR", e.what());
62bae4d07eSChris Cain             tracedError = true;
63bae4d07eSChris Cain         }
64cbad219eSEddie James     }
65cbad219eSEddie James 
66cbad219eSEddie James     if (pdrs.empty())
67cbad219eSEddie James     {
68bae4d07eSChris Cain         if (!tracedError)
69bae4d07eSChris Cain         {
7037abe9beSChris Cain             lg2::error("fetchSensorInfo: state sensor PDRs ({ID}) not present",
7137abe9beSChris Cain                        "ID", stateSetId);
72bae4d07eSChris Cain             tracedError = true;
73bae4d07eSChris Cain         }
74cbad219eSEddie James         return;
75cbad219eSEddie James     }
76cbad219eSEddie James 
77bae4d07eSChris Cain     // Found PDR
78bae4d07eSChris Cain     if (tracedError)
79bae4d07eSChris Cain     {
8037abe9beSChris Cain         lg2::info("fetchSensorInfo: found {NUM} PDRs", "NUM", pdrs.size());
81bae4d07eSChris Cain         tracedError = false;
82bae4d07eSChris Cain     }
83bae4d07eSChris Cain 
84815f9f55STom Joseph     bool offsetFound = false;
85f3a4a69fSGeorge Liu     auto stateSensorPDR =
86815f9f55STom Joseph         reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
87f3a4a69fSGeorge Liu     auto possibleStatesPtr = stateSensorPDR->possible_states;
88f3a4a69fSGeorge Liu     for (auto offset = 0; offset < stateSensorPDR->composite_sensor_count;
89f3a4a69fSGeorge Liu          offset++)
90815f9f55STom Joseph     {
91815f9f55STom Joseph         auto possibleStates =
92815f9f55STom Joseph             reinterpret_cast<const state_sensor_possible_states*>(
93815f9f55STom Joseph                 possibleStatesPtr);
94815f9f55STom Joseph 
95cbad219eSEddie James         if (possibleStates->state_set_id == stateSetId)
96815f9f55STom Joseph         {
97815f9f55STom Joseph             sensorOffset = offset;
98815f9f55STom Joseph             offsetFound = true;
99815f9f55STom Joseph             break;
100815f9f55STom Joseph         }
101815f9f55STom Joseph         possibleStatesPtr += sizeof(possibleStates->state_set_id) +
102815f9f55STom Joseph                              sizeof(possibleStates->possible_states_size) +
103815f9f55STom Joseph                              possibleStates->possible_states_size;
104815f9f55STom Joseph     }
105815f9f55STom Joseph 
106815f9f55STom Joseph     if (!offsetFound)
107815f9f55STom Joseph     {
10837abe9beSChris Cain         lg2::error("pldm: state sensor PDR not found");
109815f9f55STom Joseph         return;
110815f9f55STom Joseph     }
111815f9f55STom Joseph 
1121339ab60SMatt Spinler     // To order SensorID based on the EntityInstance.
1131339ab60SMatt Spinler     // Note that when a proc is on a DCM, the PDRs for these sensors
1141339ab60SMatt Spinler     // could have the same instance IDs but different container IDs.
1151339ab60SMatt Spinler     std::map<uint32_t, SensorID> entityInstMap{};
116815f9f55STom Joseph     for (auto& pdr : pdrs)
117815f9f55STom Joseph     {
118815f9f55STom Joseph         auto pdrPtr =
119815f9f55STom Joseph             reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
12072d01aabSChris Cain         uint32_t key = pdrPtr->sensor_id;
1211339ab60SMatt Spinler         entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->sensor_id));
122815f9f55STom Joseph     }
123815f9f55STom Joseph 
124815f9f55STom Joseph     open_power::occ::instanceID count = start;
125a49c987eSPatrick Williams     for (const auto& pair : entityInstMap)
126815f9f55STom Joseph     {
127815f9f55STom Joseph         sensorInstanceMap.emplace(pair.second, count);
128815f9f55STom Joseph         count++;
129815f9f55STom Joseph     }
130815f9f55STom Joseph }
131815f9f55STom Joseph 
sensorEvent(sdbusplus::message_t & msg)132af40808fSPatrick Williams void Interface::sensorEvent(sdbusplus::message_t& msg)
133815f9f55STom Joseph {
134815f9f55STom Joseph     if (!isOCCSensorCacheValid())
135815f9f55STom Joseph     {
136cbad219eSEddie James         fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
137cbad219eSEddie James                         sensorToOCCInstance, OCCSensorOffset);
138815f9f55STom Joseph     }
139815f9f55STom Joseph 
140cbad219eSEddie James     if (sensorToSBEInstance.empty())
141815f9f55STom Joseph     {
142cbad219eSEddie James         fetchSensorInfo(PLDM_OEM_IBM_SBE_HRESET_STATE, sensorToSBEInstance,
143cbad219eSEddie James                         SBESensorOffset);
144815f9f55STom Joseph     }
145815f9f55STom Joseph 
14672d01aabSChris Cain     TerminusID sensorTid{};
147815f9f55STom Joseph     SensorID sensorId{};
148815f9f55STom Joseph     SensorOffset msgSensorOffset{};
149815f9f55STom Joseph     EventState eventState{};
150815f9f55STom Joseph     EventState previousEventState{};
151815f9f55STom Joseph 
15272d01aabSChris Cain     msg.read(sensorTid, sensorId, msgSensorOffset, eventState,
15372d01aabSChris Cain              previousEventState);
154815f9f55STom Joseph 
155cbad219eSEddie James     if (msgSensorOffset == OCCSensorOffset)
156815f9f55STom Joseph     {
157cbad219eSEddie James         auto sensorEntry = sensorToOCCInstance.find(sensorId);
158cbad219eSEddie James 
159432dc486SEddie James         if (sensorEntry != sensorToOCCInstance.end())
160cbad219eSEddie James         {
1618b508bfbSChris Cain             const uint8_t instance = sensorEntry->second;
162755af102SChris Cain             bool validEvent = true;
1637b00cde2SChris Cain             bool isRunning = false;
164cbad219eSEddie James             if (eventState ==
165cbad219eSEddie James                 static_cast<EventState>(
166815f9f55STom Joseph                     PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
167815f9f55STom Joseph             {
16837abe9beSChris Cain                 lg2::info("PLDM: OCC{INST} is RUNNING", "INST", instance);
1697b00cde2SChris Cain                 isRunning = true;
170815f9f55STom Joseph             }
171815f9f55STom Joseph             else if (eventState ==
172815f9f55STom Joseph                      static_cast<EventState>(
173815f9f55STom Joseph                          PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
174815f9f55STom Joseph             {
17537abe9beSChris Cain                 lg2::info("PLDM: OCC{INST} has now STOPPED", "INST", instance);
176815f9f55STom Joseph             }
177bae4d07eSChris Cain             else if (eventState ==
178bae4d07eSChris Cain                      static_cast<EventState>(
179bae4d07eSChris Cain                          PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT))
180bae4d07eSChris Cain             {
18137abe9beSChris Cain                 lg2::error(
18237abe9beSChris Cain                     "PLDM: OCC{INST} has now STOPPED and system is in SAFE MODE",
18337abe9beSChris Cain                     "INST", instance);
18431a2f13aSSheldon Bailey 
18531a2f13aSSheldon Bailey                 // Setting safe mode true
18631a2f13aSSheldon Bailey                 safeModeCallBack(true);
187bae4d07eSChris Cain             }
188bae4d07eSChris Cain             else
189bae4d07eSChris Cain             {
19037abe9beSChris Cain                 lg2::warning(
19137abe9beSChris Cain                     "PLDM: Unexpected OCC Active sensor state {STATE} for OCC{INST}",
19237abe9beSChris Cain                     "STATE", eventState, "INST", instance);
193755af102SChris Cain                 validEvent = false;
194bae4d07eSChris Cain             }
195755af102SChris Cain             if (validEvent)
196755af102SChris Cain             {
197755af102SChris Cain                 if ((pldmFd > 0) && (instance == pldmResponseOcc))
198755af102SChris Cain                 {
199755af102SChris Cain                     // Waiting for a response for this OCC, can stop waiting
200755af102SChris Cain                     pldmClose();
201755af102SChris Cain                 }
202f0295f52SChris Cain                 occActiveCallBack(instance, isRunning);
203755af102SChris Cain             }
204432dc486SEddie James             return;
205cbad219eSEddie James         }
206432dc486SEddie James     }
207432dc486SEddie James 
208432dc486SEddie James     if (msgSensorOffset == SBESensorOffset)
209cbad219eSEddie James     {
210cbad219eSEddie James         auto sensorEntry = sensorToSBEInstance.find(sensorId);
211815f9f55STom Joseph 
212432dc486SEddie James         if (sensorEntry != sensorToSBEInstance.end())
213cbad219eSEddie James         {
21412d0b828SChris Cain             const uint8_t instance = sensorEntry->second;
21512d0b828SChris Cain             auto match = std::find(outstandingHResets.begin(),
21612d0b828SChris Cain                                    outstandingHResets.end(), instance);
21712d0b828SChris Cain             if (match != outstandingHResets.end())
21812d0b828SChris Cain             {
219cbad219eSEddie James                 if (eventState == static_cast<EventState>(SBE_HRESET_NOT_READY))
220cbad219eSEddie James                 {
22192dfb271SChris Cain                     lg2::warning("pldm: HRESET is NOT READY (OCC{INST})",
22237abe9beSChris Cain                                  "INST", instance);
22392dfb271SChris Cain                     // Keep waiting for status from HRESET
224cbad219eSEddie James                 }
22512d0b828SChris Cain                 else if (eventState ==
22612d0b828SChris Cain                          static_cast<EventState>(SBE_HRESET_READY))
227cbad219eSEddie James                 {
22892dfb271SChris Cain                     // Reset success, clear reset request
22992dfb271SChris Cain                     outstandingHResets.erase(match);
23012d0b828SChris Cain                     sbeCallBack(instance, true);
231cbad219eSEddie James                 }
23212d0b828SChris Cain                 else if (eventState ==
23312d0b828SChris Cain                          static_cast<EventState>(SBE_HRESET_FAILED))
234cbad219eSEddie James                 {
23592dfb271SChris Cain                     // Reset failed, clear reset request and collect SBE dump
23692dfb271SChris Cain                     outstandingHResets.erase(match);
23712d0b828SChris Cain                     sbeCallBack(instance, false);
238cbad219eSEddie James                 }
239f0295f52SChris Cain                 else
240f0295f52SChris Cain                 {
24192dfb271SChris Cain                     lg2::warning(
24237abe9beSChris Cain                         "pldm: Unexpected HRESET state {STATE} (OCC{INST})",
24337abe9beSChris Cain                         "STATE", eventState, "INST", instance);
244f0295f52SChris Cain                 }
245cbad219eSEddie James             }
24692dfb271SChris Cain             else // request was not due to our HRESET request
24792dfb271SChris Cain             {
24892dfb271SChris Cain                 if (eventState == static_cast<EventState>(SBE_HRESET_FAILED))
24992dfb271SChris Cain                 {
25092dfb271SChris Cain                     lg2::error(
25192dfb271SChris Cain                         "pldm: Unexpected HRESET state {FAILED} (OCC{INST}) when HRESET not outstanding",
25292dfb271SChris Cain                         "INST", instance);
25392dfb271SChris Cain 
25492dfb271SChris Cain                     // No recovery from failed state, so ensure comm was stopped
25592dfb271SChris Cain                     occActiveCallBack(instance, false);
25692dfb271SChris Cain                 }
25792dfb271SChris Cain             }
25812d0b828SChris Cain         }
259cbad219eSEddie James     }
260432dc486SEddie James }
261cbad219eSEddie James 
hostStateEvent(sdbusplus::message_t & msg)262af40808fSPatrick Williams void Interface::hostStateEvent(sdbusplus::message_t& msg)
263157467d0SChris Cain {
264157467d0SChris Cain     std::map<std::string, std::variant<std::string>> properties{};
265157467d0SChris Cain     std::string interface;
266157467d0SChris Cain     msg.read(interface, properties);
267157467d0SChris Cain     const auto stateEntry = properties.find("CurrentHostState");
268157467d0SChris Cain     if (stateEntry != properties.end())
269157467d0SChris Cain     {
270157467d0SChris Cain         auto stateEntryValue = stateEntry->second;
271157467d0SChris Cain         auto propVal = std::get<std::string>(stateEntryValue);
272157467d0SChris Cain         if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
273157467d0SChris Cain         {
274157467d0SChris Cain             clearData();
275*c488bac1SChris Cain             // Notify manager that host is now off
276*c488bac1SChris Cain             poweredOffCallBack();
277157467d0SChris Cain         }
278157467d0SChris Cain     }
279157467d0SChris Cain }
280157467d0SChris Cain 
clearData()281bae4d07eSChris Cain void Interface::clearData()
282bae4d07eSChris Cain {
28372d01aabSChris Cain     if (!sensorToOCCInstance.empty())
28472d01aabSChris Cain     {
28537abe9beSChris Cain         lg2::info("clearData: Clearing sensorToOCCInstance ({NUM} entries)",
28637abe9beSChris Cain                   "NUM", sensorToOCCInstance.size());
28772d01aabSChris Cain         for (auto entry : sensorToOCCInstance)
28872d01aabSChris Cain         {
28937abe9beSChris Cain             lg2::info("clearData: OCC{INST} / sensorID: {ID}", "INST",
29037abe9beSChris Cain                       entry.second, "ID", lg2::hex, entry.first);
291f0295f52SChris Cain             occActiveCallBack(entry.second, false);
29272d01aabSChris Cain         }
293815f9f55STom Joseph         sensorToOCCInstance.clear();
29472d01aabSChris Cain     }
29572d01aabSChris Cain     if (!occInstanceToEffecter.empty())
29672d01aabSChris Cain     {
29737abe9beSChris Cain         lg2::debug("clearData: Clearing occInstanceToEffecter ({NUM} entries)",
29837abe9beSChris Cain                    "NUM", occInstanceToEffecter.size());
29900325238STom Joseph         occInstanceToEffecter.clear();
30072d01aabSChris Cain     }
30172d01aabSChris Cain     if (!sensorToSBEInstance.empty())
30272d01aabSChris Cain     {
30337abe9beSChris Cain         lg2::debug("clearData: Clearing sensorToSBEInstance ({NUM} entries)",
30437abe9beSChris Cain                    "NUM", sensorToSBEInstance.size());
305cbad219eSEddie James         sensorToSBEInstance.clear();
30672d01aabSChris Cain     }
30772d01aabSChris Cain     if (!sbeInstanceToEffecter.empty())
30872d01aabSChris Cain     {
30937abe9beSChris Cain         lg2::debug("clearData: Clearing sbeInstanceToEffecter ({NUM} entries)",
31037abe9beSChris Cain                    "NUM", sbeInstanceToEffecter.size());
311cbad219eSEddie James         sbeInstanceToEffecter.clear();
312815f9f55STom Joseph     }
313*c488bac1SChris Cain     if (!outstandingHResets.empty())
314*c488bac1SChris Cain     {
315*c488bac1SChris Cain         lg2::info("clearData: clearing {NUM} outstanding HRESET requests",
316*c488bac1SChris Cain                   "NUM", outstandingHResets.size());
317*c488bac1SChris Cain         outstandingHResets.clear();
318*c488bac1SChris Cain     }
31972d01aabSChris Cain }
320815f9f55STom Joseph 
fetchEffecterInfo(uint16_t stateSetId,InstanceToEffecter & instanceToEffecterMap,CompositeEffecterCount & effecterCount,uint8_t & stateIdPos)321d7542c83SPatrick Williams void Interface::fetchEffecterInfo(
322d7542c83SPatrick Williams     uint16_t stateSetId, InstanceToEffecter& instanceToEffecterMap,
323d7542c83SPatrick Williams     CompositeEffecterCount& effecterCount, uint8_t& stateIdPos)
32400325238STom Joseph {
325cbad219eSEddie James     PdrList pdrs{};
326cbad219eSEddie James 
327cbad219eSEddie James     auto& bus = open_power::occ::utils::getBus();
328cbad219eSEddie James     try
329cbad219eSEddie James     {
330cbad219eSEddie James         auto method = bus.new_method_call(
331cbad219eSEddie James             "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
332cbad219eSEddie James             "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
333bae4d07eSChris Cain         method.append(tid, static_cast<uint16_t>(PLDM_ENTITY_PROC), stateSetId);
334cbad219eSEddie James 
335cbad219eSEddie James         auto responseMsg = bus.call(method);
336cbad219eSEddie James         responseMsg.read(pdrs);
337cbad219eSEddie James     }
338af40808fSPatrick Williams     catch (const sdbusplus::exception_t& e)
339cbad219eSEddie James     {
34037abe9beSChris Cain         lg2::error("pldm: Failed to fetch the state effecter PDRs: {ERR}",
34137abe9beSChris Cain                    "ERR", e.what());
342cbad219eSEddie James     }
343cbad219eSEddie James 
344cbad219eSEddie James     if (!pdrs.size())
345cbad219eSEddie James     {
34637abe9beSChris Cain         lg2::error("pldm: state effecter PDRs not present");
347cbad219eSEddie James         return;
348cbad219eSEddie James     }
349cbad219eSEddie James 
35000325238STom Joseph     bool offsetFound = false;
351f3a4a69fSGeorge Liu     auto stateEffecterPDR =
35200325238STom Joseph         reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
353f3a4a69fSGeorge Liu     auto possibleStatesPtr = stateEffecterPDR->possible_states;
354f3a4a69fSGeorge Liu     for (auto offset = 0; offset < stateEffecterPDR->composite_effecter_count;
355f3a4a69fSGeorge Liu          offset++)
35600325238STom Joseph     {
35700325238STom Joseph         auto possibleStates =
35800325238STom Joseph             reinterpret_cast<const state_effecter_possible_states*>(
35900325238STom Joseph                 possibleStatesPtr);
36000325238STom Joseph 
361cbad219eSEddie James         if (possibleStates->state_set_id == stateSetId)
36200325238STom Joseph         {
363cbad219eSEddie James             stateIdPos = offset;
364f3a4a69fSGeorge Liu             effecterCount = stateEffecterPDR->composite_effecter_count;
36500325238STom Joseph             offsetFound = true;
36600325238STom Joseph             break;
36700325238STom Joseph         }
36800325238STom Joseph         possibleStatesPtr += sizeof(possibleStates->state_set_id) +
36900325238STom Joseph                              sizeof(possibleStates->possible_states_size) +
37000325238STom Joseph                              possibleStates->possible_states_size;
37100325238STom Joseph     }
37200325238STom Joseph 
37300325238STom Joseph     if (!offsetFound)
37400325238STom Joseph     {
37500325238STom Joseph         return;
37600325238STom Joseph     }
37700325238STom Joseph 
3780f516528SChris Cain     std::map<uint32_t, EffecterID> entityInstMap{};
37900325238STom Joseph     for (auto& pdr : pdrs)
38000325238STom Joseph     {
38100325238STom Joseph         auto pdrPtr =
38200325238STom Joseph             reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
38372d01aabSChris Cain         uint32_t key = pdrPtr->effecter_id;
3841339ab60SMatt Spinler         entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->effecter_id));
38500325238STom Joseph     }
38600325238STom Joseph 
38700325238STom Joseph     open_power::occ::instanceID position = start;
388a49c987eSPatrick Williams     for (const auto& pair : entityInstMap)
38900325238STom Joseph     {
390cbad219eSEddie James         instanceToEffecterMap.emplace(position, pair.second);
39100325238STom Joseph         position++;
39200325238STom Joseph     }
39300325238STom Joseph }
39400325238STom Joseph 
prepareSetEffecterReq(EffecterID effecterId,CompositeEffecterCount effecterCount,uint8_t stateIdPos,uint8_t stateSetValue)395d7542c83SPatrick Williams std::vector<uint8_t> Interface::prepareSetEffecterReq(
396d7542c83SPatrick Williams     EffecterID effecterId, CompositeEffecterCount effecterCount,
397cbad219eSEddie James     uint8_t stateIdPos, uint8_t stateSetValue)
39800325238STom Joseph {
399aeba51cdSRashmica Gupta     if (!getPldmInstanceId())
4008b508bfbSChris Cain     {
4018b508bfbSChris Cain         return std::vector<uint8_t>();
4028b508bfbSChris Cain     }
4038b508bfbSChris Cain 
40400325238STom Joseph     std::vector<uint8_t> request(
40500325238STom Joseph         sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
40600325238STom Joseph         (effecterCount * sizeof(set_effecter_state_field)));
40700325238STom Joseph     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
40800325238STom Joseph     std::vector<set_effecter_state_field> stateField;
40900325238STom Joseph 
41000325238STom Joseph     for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
41100325238STom Joseph     {
412cbad219eSEddie James         if (effecterPos == stateIdPos)
41300325238STom Joseph         {
414cbad219eSEddie James             stateField.emplace_back(
415cbad219eSEddie James                 set_effecter_state_field{PLDM_REQUEST_SET, stateSetValue});
41600325238STom Joseph         }
41700325238STom Joseph         else
41800325238STom Joseph         {
41900325238STom Joseph             stateField.emplace_back(
42000325238STom Joseph                 set_effecter_state_field{PLDM_NO_CHANGE, 0});
42100325238STom Joseph         }
42200325238STom Joseph     }
42300325238STom Joseph     auto rc = encode_set_state_effecter_states_req(
424aeba51cdSRashmica Gupta         pldmInstanceID.value(), effecterId, effecterCount, stateField.data(),
4258b508bfbSChris Cain         requestMsg);
42600325238STom Joseph     if (rc != PLDM_SUCCESS)
42700325238STom Joseph     {
42837abe9beSChris Cain         lg2::error("encode set effecter states request returned error rc={RC}",
42937abe9beSChris Cain                    "RC", rc);
43000325238STom Joseph         request.clear();
43100325238STom Joseph     }
43200325238STom Joseph     return request;
43300325238STom Joseph }
43400325238STom Joseph 
resetOCC(open_power::occ::instanceID occInstanceId)43500325238STom Joseph void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
43600325238STom Joseph {
437bae4d07eSChris Cain     if (open_power::occ::utils::isHostRunning())
438bae4d07eSChris Cain     {
43900325238STom Joseph         if (!isPDREffecterCacheValid())
44000325238STom Joseph         {
441432dc486SEddie James             fetchEffecterInfo(PLDM_STATE_SET_BOOT_RESTART_CAUSE,
442432dc486SEddie James                               occInstanceToEffecter, OCCEffecterCount,
443432dc486SEddie James                               bootRestartPosition);
44400325238STom Joseph         }
44500325238STom Joseph 
44600325238STom Joseph         // Find the matching effecter for the OCC instance
44700325238STom Joseph         auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
44800325238STom Joseph         if (effecterEntry == occInstanceToEffecter.end())
44900325238STom Joseph         {
45037abe9beSChris Cain             lg2::error(
45137abe9beSChris Cain                 "pldm: Failed to find a matching effecter for OCC instance {INST}",
45237abe9beSChris Cain                 "INST", occInstanceId);
45300325238STom Joseph 
45400325238STom Joseph             return;
45500325238STom Joseph         }
45600325238STom Joseph 
457cbad219eSEddie James         // Prepare the SetStateEffecterStates request to reset the OCC
458cbad219eSEddie James         auto request = prepareSetEffecterReq(
4598b508bfbSChris Cain             effecterEntry->second, OCCEffecterCount, bootRestartPosition,
4608b508bfbSChris Cain             PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET);
461cbad219eSEddie James 
462cbad219eSEddie James         if (request.empty())
463cbad219eSEddie James         {
46437abe9beSChris Cain             lg2::error("pldm: SetStateEffecterStates OCC reset request empty");
465cbad219eSEddie James             return;
466cbad219eSEddie James         }
467cbad219eSEddie James 
468f0295f52SChris Cain         // Send request to reset the OCCs/PM Complex (and wait for response)
469f0295f52SChris Cain         msgType = MSG_OCC_RESET;
470f0295f52SChris Cain         resetInstance = occInstanceId;
471f0295f52SChris Cain         sendPldm(request, occInstanceId, true);
472bae4d07eSChris Cain     }
473bae4d07eSChris Cain     else
474bae4d07eSChris Cain     {
47537abe9beSChris Cain         lg2::error("resetOCC: HOST is not running (OCC{INST})", "INST",
47637abe9beSChris Cain                    occInstanceId);
477bae4d07eSChris Cain         clearData();
478bae4d07eSChris Cain     }
479cbad219eSEddie James }
480cbad219eSEddie James 
sendHRESET(open_power::occ::instanceID sbeInstanceId)481cbad219eSEddie James void Interface::sendHRESET(open_power::occ::instanceID sbeInstanceId)
482cbad219eSEddie James {
483bae4d07eSChris Cain     if (open_power::occ::utils::isHostRunning())
484bae4d07eSChris Cain     {
485cbad219eSEddie James         if (sbeInstanceToEffecter.empty())
486cbad219eSEddie James         {
487432dc486SEddie James             fetchEffecterInfo(PLDM_OEM_IBM_SBE_MAINTENANCE_STATE,
488cbad219eSEddie James                               sbeInstanceToEffecter, SBEEffecterCount,
489cbad219eSEddie James                               sbeMaintenanceStatePosition);
490cbad219eSEddie James         }
491cbad219eSEddie James 
492cbad219eSEddie James         auto effecterEntry = sbeInstanceToEffecter.find(sbeInstanceId);
493cbad219eSEddie James         if (effecterEntry == sbeInstanceToEffecter.end())
494cbad219eSEddie James         {
49537abe9beSChris Cain             lg2::error(
49637abe9beSChris Cain                 "pldm: Failed to find a matching effecter for SBE instance {INST}",
49737abe9beSChris Cain                 "INST", sbeInstanceId);
498cbad219eSEddie James             return;
499cbad219eSEddie James         }
500cbad219eSEddie James 
501cbad219eSEddie James         // Prepare the SetStateEffecterStates request to HRESET the SBE
502cbad219eSEddie James         auto request = prepareSetEffecterReq(
5038b508bfbSChris Cain             effecterEntry->second, SBEEffecterCount,
504cbad219eSEddie James             sbeMaintenanceStatePosition, SBE_RETRY_REQUIRED);
505cbad219eSEddie James 
506cbad219eSEddie James         if (request.empty())
507cbad219eSEddie James         {
50837abe9beSChris Cain             lg2::error("pldm: SetStateEffecterStates HRESET request empty");
509cbad219eSEddie James             return;
510cbad219eSEddie James         }
511cbad219eSEddie James 
512f0295f52SChris Cain         // Send request to issue HRESET of SBE (and wait for response)
513f0295f52SChris Cain         msgType = MSG_HRESET;
514f0295f52SChris Cain         resetInstance = sbeInstanceId;
515f0295f52SChris Cain         sendPldm(request, sbeInstanceId, true);
51612d0b828SChris Cain         outstandingHResets.insert(sbeInstanceId);
517bae4d07eSChris Cain     }
518bae4d07eSChris Cain     else
519bae4d07eSChris Cain     {
52037abe9beSChris Cain         lg2::error("sendHRESET: HOST is not running (OCC{INST})", "INST",
52137abe9beSChris Cain                    sbeInstanceId);
522bae4d07eSChris Cain         clearData();
523bae4d07eSChris Cain     }
524cbad219eSEddie James }
525cbad219eSEddie James 
getPldmInstanceId()526aeba51cdSRashmica Gupta bool Interface::getPldmInstanceId()
527cbad219eSEddie James {
528db38e91aSRashmica Gupta     pldm_instance_id_t id;
529aeba51cdSRashmica Gupta     if (!pldmInstanceID)
5308b508bfbSChris Cain     {
5318b508bfbSChris Cain         // Request new instance ID
532db38e91aSRashmica Gupta         int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);
533db38e91aSRashmica Gupta         if (rc == -EAGAIN)
53400325238STom Joseph         {
535db38e91aSRashmica Gupta             std::this_thread::sleep_for(std::chrono::milliseconds(100));
536db38e91aSRashmica Gupta             rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);
537db38e91aSRashmica Gupta         }
538db38e91aSRashmica Gupta 
539db38e91aSRashmica Gupta         if (rc)
540db38e91aSRashmica Gupta         {
54137abe9beSChris Cain             lg2::error(
54237abe9beSChris Cain                 "getPldmInstanceId: Failed to alloc ID for TID {TID}. RC{RC}",
54337abe9beSChris Cain                 "TID", tid, "RC", rc);
544db38e91aSRashmica Gupta             return false;
545db38e91aSRashmica Gupta         }
546db38e91aSRashmica Gupta         pldmInstanceID.emplace(id);
547755af102SChris Cain         if (!throttleTraces)
548755af102SChris Cain         {
54937abe9beSChris Cain             lg2::info("got id {ID} and set PldmInstanceId to {INST}", "ID", id,
55037abe9beSChris Cain                       "INST", pldmInstanceID.value());
55100325238STom Joseph         }
552755af102SChris Cain     }
553db38e91aSRashmica Gupta     return true;
5548b508bfbSChris Cain }
55500325238STom Joseph 
freePldmInstanceId()556db38e91aSRashmica Gupta void Interface::freePldmInstanceId()
557db38e91aSRashmica Gupta {
558db38e91aSRashmica Gupta     if (pldmInstanceID)
559db38e91aSRashmica Gupta     {
560db38e91aSRashmica Gupta         int rc = pldm_instance_id_free(pldmInstanceIdDb, tid,
561db38e91aSRashmica Gupta                                        pldmInstanceID.value());
562db38e91aSRashmica Gupta         if (rc)
563db38e91aSRashmica Gupta         {
56437abe9beSChris Cain             lg2::error(
56537abe9beSChris Cain                 "freePldmInstanceId: Failed to free ID {ID} for TID {TID}. RC{RC}",
56637abe9beSChris Cain                 "ID", pldmInstanceID.value(), "TID", tid, "RC", rc);
567db38e91aSRashmica Gupta             return;
568db38e91aSRashmica Gupta         }
569db38e91aSRashmica Gupta         if (!throttleTraces)
570db38e91aSRashmica Gupta         {
57137abe9beSChris Cain             lg2::info("Freed PLDM instance ID {ID}", "ID",
57237abe9beSChris Cain                       pldmInstanceID.value());
573db38e91aSRashmica Gupta         }
574db38e91aSRashmica Gupta         pldmInstanceID = std::nullopt;
575db38e91aSRashmica Gupta     }
576cbad219eSEddie James }
57700325238STom Joseph 
openMctpDemuxTransport()5786213f199SLakshmi Yadlapati [[maybe_unused]] int Interface::openMctpDemuxTransport()
57952328cb4SRashmica Gupta {
5806213f199SLakshmi Yadlapati     impl.mctpDemux = nullptr;
5816213f199SLakshmi Yadlapati     int rc = pldm_transport_mctp_demux_init(&impl.mctpDemux);
58252328cb4SRashmica Gupta     if (rc)
58352328cb4SRashmica Gupta     {
58437abe9beSChris Cain         lg2::error(
58537abe9beSChris Cain             "openMctpDemuxTransport: Failed to init MCTP demux transport, errno={ERR}/{STR}",
58637abe9beSChris Cain             "ERR", rc, "STR", strerror(rc));
58752328cb4SRashmica Gupta         return -1;
58852328cb4SRashmica Gupta     }
58952328cb4SRashmica Gupta 
5906213f199SLakshmi Yadlapati     if (pldm_transport_mctp_demux_map_tid(impl.mctpDemux, mctpEid, mctpEid))
59152328cb4SRashmica Gupta     {
59237abe9beSChris Cain         lg2::error(
59337abe9beSChris Cain             "openMctpDemuxTransport: Failed to setup tid to eid mapping, errno={ERR}/{STR}",
59437abe9beSChris Cain             "ERR", errno, "STR", strerror(errno));
59552328cb4SRashmica Gupta         pldmClose();
59652328cb4SRashmica Gupta         return -1;
59752328cb4SRashmica Gupta     }
5986213f199SLakshmi Yadlapati     pldmTransport = pldm_transport_mctp_demux_core(impl.mctpDemux);
59952328cb4SRashmica Gupta 
60052328cb4SRashmica Gupta     struct pollfd pollfd;
60152328cb4SRashmica Gupta     if (pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd))
60252328cb4SRashmica Gupta     {
60337abe9beSChris Cain         lg2::error(
60437abe9beSChris Cain             "openMctpDemuxTransport: Failed to get pollfd , errno={ERR}/{STR}",
60537abe9beSChris Cain             "ERR", errno, "STR", strerror(errno));
60652328cb4SRashmica Gupta         pldmClose();
60752328cb4SRashmica Gupta         return -1;
60852328cb4SRashmica Gupta     }
60952328cb4SRashmica Gupta     pldmFd = pollfd.fd;
61052328cb4SRashmica Gupta     if (!throttleTraces)
61152328cb4SRashmica Gupta     {
61237abe9beSChris Cain         lg2::info("openMctpDemuxTransport: pldmFd has fd={FD}", "FD", pldmFd);
61352328cb4SRashmica Gupta     }
61452328cb4SRashmica Gupta     return 0;
61552328cb4SRashmica Gupta }
61652328cb4SRashmica Gupta 
openAfMctpTransport()6176213f199SLakshmi Yadlapati [[maybe_unused]] int Interface::openAfMctpTransport()
6186213f199SLakshmi Yadlapati {
6196213f199SLakshmi Yadlapati     impl.afMctp = nullptr;
6206213f199SLakshmi Yadlapati     int rc = pldm_transport_af_mctp_init(&impl.afMctp);
6216213f199SLakshmi Yadlapati     if (rc)
6226213f199SLakshmi Yadlapati     {
62337abe9beSChris Cain         lg2::error(
62437abe9beSChris Cain             "openAfMctpTransport: Failed to init af MCTP transport, errno={ERR}/{STR}",
62537abe9beSChris Cain             "ERR", rc, "STR", strerror(rc));
6266213f199SLakshmi Yadlapati         return -1;
6276213f199SLakshmi Yadlapati     }
6286213f199SLakshmi Yadlapati 
6296213f199SLakshmi Yadlapati     if (pldm_transport_af_mctp_map_tid(impl.afMctp, mctpEid, mctpEid))
6306213f199SLakshmi Yadlapati     {
63137abe9beSChris Cain         lg2::error(
63237abe9beSChris Cain             "openAfMctpTransport: Failed to setup tid to eid mapping, errno={ERR}/{STR}",
63337abe9beSChris Cain             "ERR", errno, "STR", strerror(errno));
6346213f199SLakshmi Yadlapati         pldmClose();
6356213f199SLakshmi Yadlapati         return -1;
6366213f199SLakshmi Yadlapati     }
6376213f199SLakshmi Yadlapati     pldmTransport = pldm_transport_af_mctp_core(impl.afMctp);
6386213f199SLakshmi Yadlapati 
6396213f199SLakshmi Yadlapati     struct pollfd pollfd;
6406213f199SLakshmi Yadlapati     if (pldm_transport_af_mctp_init_pollfd(pldmTransport, &pollfd))
6416213f199SLakshmi Yadlapati     {
64237abe9beSChris Cain         lg2::error(
64337abe9beSChris Cain             "openAfMctpTransport: Failed to get pollfd , errno={ERR}/{STR}",
64437abe9beSChris Cain             "ERR", errno, "STR", strerror(errno));
6456213f199SLakshmi Yadlapati         pldmClose();
6466213f199SLakshmi Yadlapati         return -1;
6476213f199SLakshmi Yadlapati     }
6486213f199SLakshmi Yadlapati     pldmFd = pollfd.fd;
6496213f199SLakshmi Yadlapati     if (!throttleTraces)
6506213f199SLakshmi Yadlapati     {
65137abe9beSChris Cain         lg2::info("openAfMctpTransport: pldmFd has fd={FD}", "FD", pldmFd);
6526213f199SLakshmi Yadlapati     }
6536213f199SLakshmi Yadlapati     return 0;
6546213f199SLakshmi Yadlapati }
6556213f199SLakshmi Yadlapati 
pldmOpen()65652328cb4SRashmica Gupta int Interface::pldmOpen()
65752328cb4SRashmica Gupta {
65852328cb4SRashmica Gupta     if (pldmTransport)
65952328cb4SRashmica Gupta     {
66037abe9beSChris Cain         lg2::error("pldmOpen: pldmTransport already setup!, errno={ERR}/{STR}",
66137abe9beSChris Cain                    "ERR", errno, "STR", strerror(errno));
66252328cb4SRashmica Gupta         return -1;
66352328cb4SRashmica Gupta     }
6646213f199SLakshmi Yadlapati #if defined(PLDM_TRANSPORT_WITH_MCTP_DEMUX)
66552328cb4SRashmica Gupta     return openMctpDemuxTransport();
6666213f199SLakshmi Yadlapati #elif defined(PLDM_TRANSPORT_WITH_AF_MCTP)
6676213f199SLakshmi Yadlapati     return openAfMctpTransport();
6686213f199SLakshmi Yadlapati #else
66937abe9beSChris Cain     lg2::error("pldmOpen: Undefined pldmTransport!, errno={ERR}/{STR}", "ERR",
67037abe9beSChris Cain                errno, "STR", strerror(errno));
6716213f199SLakshmi Yadlapati     return -1;
6726213f199SLakshmi Yadlapati #endif
6736213f199SLakshmi Yadlapati 
6746213f199SLakshmi Yadlapati     return 0;
67552328cb4SRashmica Gupta }
67652328cb4SRashmica Gupta 
sendPldm(const std::vector<uint8_t> & request,const uint8_t instance,const bool rspExpected)677bae4d07eSChris Cain void Interface::sendPldm(const std::vector<uint8_t>& request,
678bae4d07eSChris Cain                          const uint8_t instance, const bool rspExpected)
67900325238STom Joseph {
680aeba51cdSRashmica Gupta     if (!pldmInstanceID)
6818b508bfbSChris Cain     {
68237abe9beSChris Cain         lg2::error("sendPldm: No PLDM Instance ID found!");
6838b508bfbSChris Cain         return;
6848b508bfbSChris Cain     }
6858b508bfbSChris Cain 
68652328cb4SRashmica Gupta     auto rc = pldmOpen();
68752328cb4SRashmica Gupta     if (rc)
68800325238STom Joseph     {
68988811adcSEddie James         if (!throttleTraces)
69088811adcSEddie James         {
69137abe9beSChris Cain             lg2::error("sendPldm: pldmOpen failed rc={RC}", "RC", rc);
69288811adcSEddie James         }
693db38e91aSRashmica Gupta         freePldmInstanceId();
69400325238STom Joseph         return;
69500325238STom Joseph     }
696cbad219eSEddie James 
69752328cb4SRashmica Gupta     pldm_tid_t pldmTID = static_cast<pldm_tid_t>(mctpEid);
69800325238STom Joseph     // Send the PLDM request message to HBRT
699bae4d07eSChris Cain     if (rspExpected)
700d1b6826aSChris Cain     {
701bae4d07eSChris Cain         // Register callback when response is available
702bae4d07eSChris Cain         registerPldmRspCallback();
703bae4d07eSChris Cain 
704f0295f52SChris Cain         using namespace std::literals::chrono_literals;
705f0295f52SChris Cain         std::chrono::duration timeout = 8s;
706f0295f52SChris Cain         if ((msgType == MSG_OCC_RESET) || (msgType == MSG_HRESET))
707f0295f52SChris Cain         {
708f0295f52SChris Cain             timeout = 30s;
709f0295f52SChris Cain         }
710f0295f52SChris Cain 
711bae4d07eSChris Cain         // Send PLDM request
712755af102SChris Cain         if (!throttleTraces)
713755af102SChris Cain         {
71437abe9beSChris Cain             lg2::info("sendPldm: calling pldm_transport_send_msg(OCC{INST}, "
71537abe9beSChris Cain                       "instance:{ID}, {LEN} bytes, timeout {TO})",
71637abe9beSChris Cain                       "INST", instance, "ID", pldmInstanceID.value(), "LEN",
71737abe9beSChris Cain                       request.size(), "TO", timeout.count());
718755af102SChris Cain         }
719bae4d07eSChris Cain         pldmResponseReceived = false;
720bae4d07eSChris Cain         pldmResponseTimeout = false;
721bae4d07eSChris Cain         pldmResponseOcc = instance;
72252328cb4SRashmica Gupta         auto pldmRc = pldm_transport_send_msg(pldmTransport, pldmTID,
72352328cb4SRashmica Gupta                                               request.data(), request.size());
724bae4d07eSChris Cain         auto sendErrno = errno;
725bae4d07eSChris Cain         if (pldmRc != PLDM_REQUESTER_SUCCESS)
726bae4d07eSChris Cain         {
72737abe9beSChris Cain             lg2::error(
72837abe9beSChris Cain                 "sendPldm: pldm_transport_send_msg failed with rc={RC} and errno={ERR}/{STR}",
72937abe9beSChris Cain                 "RC",
73037abe9beSChris Cain                 static_cast<std::underlying_type_t<pldm_requester_error_codes>>(
7315161a028SChris Cain                     pldmRc),
73237abe9beSChris Cain                 "ERR", sendErrno, "STR", strerror(sendErrno));
733bae4d07eSChris Cain             pldmClose();
734bae4d07eSChris Cain             return;
735bae4d07eSChris Cain         }
736bae4d07eSChris Cain 
737bae4d07eSChris Cain         // start timer waiting for the response
738f0295f52SChris Cain         pldmRspTimer.restartOnce(timeout);
739bae4d07eSChris Cain 
740bae4d07eSChris Cain         // Wait for response/timeout
741bae4d07eSChris Cain     }
742bae4d07eSChris Cain     else // not expecting the response
743bae4d07eSChris Cain     {
744755af102SChris Cain         if (!throttleTraces)
745755af102SChris Cain         {
74637abe9beSChris Cain             lg2::info(
74737abe9beSChris Cain                 "sendPldm: calling pldm_transport_send_msg(mctpID:{ID}, fd:{FD}, "
74837abe9beSChris Cain                 "{LEN} bytes) for OCC{INST}",
74937abe9beSChris Cain                 "ID", mctpEid, "FD", pldmFd, "LEN", request.size(), "INST",
75037abe9beSChris Cain                 instance);
751755af102SChris Cain         }
75252328cb4SRashmica Gupta         auto rc = pldm_transport_send_msg(pldmTransport, pldmTID,
75352328cb4SRashmica Gupta                                           request.data(), request.size());
754bae4d07eSChris Cain         auto sendErrno = errno;
75500325238STom Joseph         if (rc)
75600325238STom Joseph         {
75737abe9beSChris Cain             lg2::error(
75837abe9beSChris Cain                 "sendPldm: pldm_transport_send_msg(mctpID:{ID}, fd:{FD}, {LEN} bytes) "
75937abe9beSChris Cain                 "failed with rc={RC} and errno={ERR}/{STR}",
76037abe9beSChris Cain                 "ID", mctpEid, "FD", pldmFd, "LEN", request.size(), "RC",
76137abe9beSChris Cain                 static_cast<std::underlying_type_t<pldm_requester_error_codes>>(
76237abe9beSChris Cain                     rc),
76337abe9beSChris Cain                 "ERR", sendErrno, "STR", strerror(sendErrno));
76400325238STom Joseph         }
765bae4d07eSChris Cain         pldmClose();
766bae4d07eSChris Cain     }
767bae4d07eSChris Cain }
76800325238STom Joseph 
769bae4d07eSChris Cain // Attaches the FD to event loop and registers the callback handler
registerPldmRspCallback()770bae4d07eSChris Cain void Interface::registerPldmRspCallback()
771bae4d07eSChris Cain {
772bae4d07eSChris Cain     decltype(eventSource.get()) sourcePtr = nullptr;
773f0295f52SChris Cain     int rc = 0;
774f0295f52SChris Cain     if ((msgType == MSG_OCC_RESET) || (msgType == MSG_HRESET))
775f0295f52SChris Cain     {
776f0295f52SChris Cain         rc = sd_event_add_io(event.get(), &sourcePtr, pldmFd, EPOLLIN,
777f0295f52SChris Cain                              pldmResetCallback, this);
778f0295f52SChris Cain     }
779f0295f52SChris Cain     else
780f0295f52SChris Cain     {
781f0295f52SChris Cain         rc = sd_event_add_io(event.get(), &sourcePtr, pldmFd, EPOLLIN,
782bae4d07eSChris Cain                              pldmRspCallback, this);
783f0295f52SChris Cain     }
784bae4d07eSChris Cain     if (rc < 0)
78500325238STom Joseph     {
78637abe9beSChris Cain         lg2::error(
78737abe9beSChris Cain             "registerPldmRspCallback: sd_event_add_io: Error({ERR})={STR} : fd={FD} (msgType={MSG})",
78837abe9beSChris Cain             "ERR", rc, "STR", strerror(-rc), "FD", pldmFd, "MSG", msgType);
789d1b6826aSChris Cain     }
790d1b6826aSChris Cain     else
791d1b6826aSChris Cain     {
792bae4d07eSChris Cain         // puts sourcePtr in the event source.
793bae4d07eSChris Cain         eventSource.reset(sourcePtr);
794bae4d07eSChris Cain     }
795bae4d07eSChris Cain }
796bae4d07eSChris Cain 
797bae4d07eSChris Cain // Add a timer to the event loop, default 30s.
pldmRspExpired()798bae4d07eSChris Cain void Interface::pldmRspExpired()
799bae4d07eSChris Cain {
800bae4d07eSChris Cain     if (!pldmResponseReceived)
801bae4d07eSChris Cain     {
802755af102SChris Cain         if (!throttleTraces)
803755af102SChris Cain         {
80437abe9beSChris Cain             lg2::warning(
80537abe9beSChris Cain                 "pldmRspExpired: timerCallback - timeout waiting for pldm "
80637abe9beSChris Cain                 "response to msg:{MSG} for OCC{INST}",
80737abe9beSChris Cain                 "MSG", msgType, "INST", pldmResponseOcc);
808755af102SChris Cain         }
809bae4d07eSChris Cain         pldmResponseTimeout = true;
810bae4d07eSChris Cain         if (pldmFd)
811bae4d07eSChris Cain         {
812bae4d07eSChris Cain             pldmClose();
813bae4d07eSChris Cain         }
814f0295f52SChris Cain         if (msgType == MSG_OCC_RESET)
815f0295f52SChris Cain         {
816f0295f52SChris Cain             // reset not acked, try again
81737abe9beSChris Cain             lg2::error("pldmRspExpired: retrying reset request for OCC{INST}",
81837abe9beSChris Cain                        "INST", pldmResponseOcc);
819f0295f52SChris Cain             resetOCC(pldmResponseOcc);
820f0295f52SChris Cain         }
821bae4d07eSChris Cain     }
822bae4d07eSChris Cain     return;
823bae4d07eSChris Cain };
824bae4d07eSChris Cain 
pldmClose()825bae4d07eSChris Cain void Interface::pldmClose()
826bae4d07eSChris Cain {
827db38e91aSRashmica Gupta     freePldmInstanceId();
828bae4d07eSChris Cain     if (pldmRspTimer.isEnabled())
829bae4d07eSChris Cain     {
830bae4d07eSChris Cain         // stop PLDM response timer
831bae4d07eSChris Cain         pldmRspTimer.setEnabled(false);
832bae4d07eSChris Cain     }
83352328cb4SRashmica Gupta 
8346213f199SLakshmi Yadlapati #if defined(PLDM_TRANSPORT_WITH_MCTP_DEMUX)
8356213f199SLakshmi Yadlapati     pldm_transport_mctp_demux_destroy(impl.mctpDemux);
8366213f199SLakshmi Yadlapati     impl.mctpDemux = NULL;
8376213f199SLakshmi Yadlapati #elif defined(PLDM_TRANSPORT_WITH_AF_MCTP)
8386213f199SLakshmi Yadlapati     pldm_transport_af_mctp_destroy(impl.afMctp);
8396213f199SLakshmi Yadlapati     impl.afMctp = NULL;
8406213f199SLakshmi Yadlapati #endif
841bae4d07eSChris Cain     pldmFd = -1;
84252328cb4SRashmica Gupta     pldmTransport = NULL;
843bae4d07eSChris Cain     eventSource.reset();
844bae4d07eSChris Cain }
845bae4d07eSChris Cain 
pldmRspCallback(sd_event_source *,int fd,uint32_t revents,void * userData)84652328cb4SRashmica Gupta int Interface::pldmRspCallback(sd_event_source* /*es*/,
84752328cb4SRashmica Gupta                                __attribute__((unused)) int fd, uint32_t revents,
84852328cb4SRashmica Gupta                                void* userData)
849bae4d07eSChris Cain {
850bae4d07eSChris Cain     if (!(revents & EPOLLIN))
851bae4d07eSChris Cain     {
85237abe9beSChris Cain         lg2::info("pldmRspCallback - revents={NUM}", "NUM", lg2::hex, revents);
853bae4d07eSChris Cain         return -1;
854bae4d07eSChris Cain     }
855bae4d07eSChris Cain 
856bae4d07eSChris Cain     auto pldmIface = static_cast<Interface*>(userData);
857bae4d07eSChris Cain 
858aeba51cdSRashmica Gupta     if (!pldmIface->pldmInstanceID)
8598b508bfbSChris Cain     {
86037abe9beSChris Cain         lg2::error("pldmRspCallback: No outstanding PLDM Instance ID found");
8618b508bfbSChris Cain         return -1;
8628b508bfbSChris Cain     }
8638b508bfbSChris Cain 
864bae4d07eSChris Cain     uint8_t* responseMsg = nullptr;
865bae4d07eSChris Cain     size_t responseMsgSize{};
86652328cb4SRashmica Gupta     pldm_tid_t pldmTID = static_cast<pldm_tid_t>(mctpEid);
867bae4d07eSChris Cain 
868755af102SChris Cain     if (!throttleTraces)
869755af102SChris Cain     {
87037abe9beSChris Cain         lg2::info(
87137abe9beSChris Cain             "pldmRspCallback: calling pldm_transport_recv_msg() instance:{INST}",
87237abe9beSChris Cain             "INST", pldmIface->pldmInstanceID.value());
873755af102SChris Cain     }
87452328cb4SRashmica Gupta     auto rc = pldm_transport_recv_msg(pldmIface->pldmTransport, &pldmTID,
87552328cb4SRashmica Gupta                                       (void**)&responseMsg, &responseMsgSize);
876bae4d07eSChris Cain     int lastErrno = errno;
877d1b6826aSChris Cain     if (rc)
878d1b6826aSChris Cain     {
879755af102SChris Cain         if (!throttleTraces)
880755af102SChris Cain         {
88137abe9beSChris Cain             lg2::error(
88237abe9beSChris Cain                 "pldmRspCallback: pldm_transport_recv_msg failed with rc={RC}, errno={ERR}/{STR}",
88337abe9beSChris Cain                 "RC",
88437abe9beSChris Cain                 static_cast<std::underlying_type_t<pldm_requester_error_codes>>(
88537abe9beSChris Cain                     rc),
88637abe9beSChris Cain                 "ERR", lastErrno, "STR", strerror(lastErrno));
887755af102SChris Cain         }
888bae4d07eSChris Cain         return -1;
889bae4d07eSChris Cain     }
8908b508bfbSChris Cain 
8918b508bfbSChris Cain     // We got the response for the PLDM request msg that was sent
892755af102SChris Cain     if (!throttleTraces)
893755af102SChris Cain     {
89437abe9beSChris Cain         lg2::info(
89537abe9beSChris Cain             "pldmRspCallback: pldm_transport_recv_msg() rsp was {LEN} bytes",
89637abe9beSChris Cain             "LEN", responseMsgSize);
897755af102SChris Cain     }
898bae4d07eSChris Cain 
899bae4d07eSChris Cain     if (pldmIface->pldmRspTimer.isEnabled())
900bae4d07eSChris Cain     {
901bae4d07eSChris Cain         // stop PLDM response timer
902bae4d07eSChris Cain         pldmIface->pldmRspTimer.setEnabled(false);
903bae4d07eSChris Cain     }
904bae4d07eSChris Cain 
90592dfb271SChris Cain     // instance ID will get freed on pldmClose()
9068b508bfbSChris Cain 
907bae4d07eSChris Cain     // Set pointer to autodelete
908d7542c83SPatrick Williams     std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{
909d7542c83SPatrick Williams         responseMsg, std::free};
910bae4d07eSChris Cain 
911bae4d07eSChris Cain     auto response = reinterpret_cast<pldm_msg*>(responseMsgPtr.get());
912bae4d07eSChris Cain     if (response->payload[0] != PLDM_SUCCESS)
913bae4d07eSChris Cain     {
91437abe9beSChris Cain         lg2::error("pldmRspCallback: payload[0] was not success: {STATUS}",
91537abe9beSChris Cain                    "STATUS", response->payload[0]);
916bae4d07eSChris Cain         pldmIface->pldmClose();
917bae4d07eSChris Cain         return -1;
918bae4d07eSChris Cain     }
919bae4d07eSChris Cain 
920bae4d07eSChris Cain     // Decode the response
921bae4d07eSChris Cain     uint8_t compCode = 0, sensorCount = 1;
922bae4d07eSChris Cain     get_sensor_state_field field[6];
923bae4d07eSChris Cain     responseMsgSize -= sizeof(pldm_msg_hdr);
924bae4d07eSChris Cain     auto msgRc = decode_get_state_sensor_readings_resp(
925bae4d07eSChris Cain         response, responseMsgSize, &compCode, &sensorCount, field);
926bae4d07eSChris Cain     if ((msgRc != PLDM_SUCCESS) || (compCode != PLDM_SUCCESS))
927bae4d07eSChris Cain     {
92837abe9beSChris Cain         lg2::error(
92937abe9beSChris Cain             "pldmRspCallback: decode_get_state_sensor_readings failed with rc={RC} and compCode={CC}",
93037abe9beSChris Cain             "RC", msgRc, "CC", compCode);
931bae4d07eSChris Cain         pldmIface->pldmClose();
932bae4d07eSChris Cain         return -1;
933bae4d07eSChris Cain     }
934bae4d07eSChris Cain 
935bae4d07eSChris Cain     pldmIface->pldmClose();
936bae4d07eSChris Cain 
937bae4d07eSChris Cain     const uint8_t instance = pldmIface->pldmResponseOcc;
938bae4d07eSChris Cain     const uint8_t occSensorState = field[0].present_state;
939bae4d07eSChris Cain     pldmIface->pldmResponseReceived = true;
940bae4d07eSChris Cain 
941bae4d07eSChris Cain     if (occSensorState == PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE)
942bae4d07eSChris Cain     {
94337abe9beSChris Cain         lg2::info("pldmRspCallback: OCC{INST} is RUNNING", "INST", instance);
944f0295f52SChris Cain         pldmIface->occActiveCallBack(instance, true);
945bae4d07eSChris Cain     }
946733b201fSChris Cain     else if (occSensorState ==
947733b201fSChris Cain              PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT)
948733b201fSChris Cain     {
94937abe9beSChris Cain         lg2::error(
95037abe9beSChris Cain             "pldmRspCallback: OCC{INST} has now STOPPED and system is in SAFE MODE",
95137abe9beSChris Cain             "INST", instance);
95231a2f13aSSheldon Bailey 
95331a2f13aSSheldon Bailey         // Setting safe mode true
95431a2f13aSSheldon Bailey         pldmIface->safeModeCallBack(true);
95531a2f13aSSheldon Bailey 
956f0295f52SChris Cain         pldmIface->occActiveCallBack(instance, false);
957733b201fSChris Cain     }
958755af102SChris Cain     else if (occSensorState ==
959755af102SChris Cain              PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED)
960bae4d07eSChris Cain     {
96137abe9beSChris Cain         lg2::info("pldmRspCallback: OCC{INST} is not running", "INST",
96237abe9beSChris Cain                   instance);
963f0295f52SChris Cain         pldmIface->occActiveCallBack(instance, false);
964755af102SChris Cain     }
965755af102SChris Cain     else
966c9dc4418SChris Cain     {
967c9dc4418SChris Cain         const size_t rspLength = responseMsgSize + sizeof(pldm_msg_hdr);
968c9dc4418SChris Cain         std::vector<std::uint8_t> pldmResponse(rspLength);
969c9dc4418SChris Cain         memcpy(&pldmResponse[0], reinterpret_cast<std::uint8_t*>(response),
970c9dc4418SChris Cain                rspLength);
971755af102SChris Cain         if (!throttleTraces)
972755af102SChris Cain         {
97337abe9beSChris Cain             lg2::warning(
97437abe9beSChris Cain                 "pldmRspCallback: Unexpected State: {STATE} - PLDM response "
97537abe9beSChris Cain                 "({LEN} bytes) for OCC{INST}:",
97637abe9beSChris Cain                 "STATE", occSensorState, "LEN", rspLength, "INST", instance);
977c9dc4418SChris Cain             dump_hex(pldmResponse);
978c9dc4418SChris Cain         }
979bae4d07eSChris Cain     }
980bae4d07eSChris Cain 
981bae4d07eSChris Cain     return 0;
982bae4d07eSChris Cain };
983bae4d07eSChris Cain 
pldmResetCallback(sd_event_source *,int fd,uint32_t revents,void * userData)984f0295f52SChris Cain int Interface::pldmResetCallback(sd_event_source* /*es*/,
985f0295f52SChris Cain                                  __attribute__((unused)) int fd,
986f0295f52SChris Cain                                  uint32_t revents, void* userData)
987f0295f52SChris Cain {
988f0295f52SChris Cain     if (!(revents & EPOLLIN))
989f0295f52SChris Cain     {
99037abe9beSChris Cain         lg2::info("pldmResetCallback - revents={NUM}", "NUM", lg2::hex,
99137abe9beSChris Cain                   revents);
992f0295f52SChris Cain         return -1;
993f0295f52SChris Cain     }
994f0295f52SChris Cain 
995f0295f52SChris Cain     auto pldmIface = static_cast<Interface*>(userData);
996f0295f52SChris Cain 
997f0295f52SChris Cain     if (!pldmIface->pldmInstanceID)
998f0295f52SChris Cain     {
99937abe9beSChris Cain         lg2::error("pldmResetCallback: No outstanding PLDM Instance ID found");
1000f0295f52SChris Cain         return -1;
1001f0295f52SChris Cain     }
1002f0295f52SChris Cain 
1003f0295f52SChris Cain     uint8_t* responseMsg = nullptr;
1004f0295f52SChris Cain     size_t responseMsgSize{};
1005f0295f52SChris Cain     pldm_tid_t pldmTID = static_cast<pldm_tid_t>(mctpEid);
1006f0295f52SChris Cain 
1007f0295f52SChris Cain     if (!throttleTraces)
1008f0295f52SChris Cain     {
100937abe9beSChris Cain         lg2::info(
101037abe9beSChris Cain             "pldmResetCallback: calling pldm_transport_recv_msg() instance:{ID}",
101137abe9beSChris Cain             "ID", pldmIface->pldmInstanceID.value());
1012f0295f52SChris Cain     }
1013f0295f52SChris Cain     auto rc = pldm_transport_recv_msg(pldmIface->pldmTransport, &pldmTID,
1014f0295f52SChris Cain                                       (void**)&responseMsg, &responseMsgSize);
1015f0295f52SChris Cain     int lastErrno = errno;
1016f0295f52SChris Cain     if (rc)
1017f0295f52SChris Cain     {
1018f0295f52SChris Cain         if (!throttleTraces)
1019f0295f52SChris Cain         {
102037abe9beSChris Cain             lg2::error(
102137abe9beSChris Cain                 "pldmResetCallback: pldm_transport_recv_msg failed with rc={RC}, errno={ERR}/{STR}",
102237abe9beSChris Cain                 "RC",
102337abe9beSChris Cain                 static_cast<std::underlying_type_t<pldm_requester_error_codes>>(
102437abe9beSChris Cain                     rc),
102537abe9beSChris Cain                 "ERR", lastErrno, "STR", strerror(lastErrno));
1026f0295f52SChris Cain         }
1027f0295f52SChris Cain         return -1;
1028f0295f52SChris Cain     }
1029f0295f52SChris Cain 
1030f0295f52SChris Cain     // We got the response for the PLDM request msg that was sent
1031f0295f52SChris Cain     if (!throttleTraces)
1032f0295f52SChris Cain     {
103337abe9beSChris Cain         lg2::info(
103437abe9beSChris Cain             "pldmResetCallback: pldm_transport_recv_msg() rsp was {LEN} bytes",
103537abe9beSChris Cain             "LEN", responseMsgSize);
1036f0295f52SChris Cain     }
1037f0295f52SChris Cain 
1038f0295f52SChris Cain     if (pldmIface->pldmRspTimer.isEnabled())
1039f0295f52SChris Cain     {
1040f0295f52SChris Cain         // stop PLDM response timer
1041f0295f52SChris Cain         pldmIface->pldmRspTimer.setEnabled(false);
1042f0295f52SChris Cain     }
1043f0295f52SChris Cain 
104492dfb271SChris Cain     // instance ID will get freed on pldmClose()
1045f0295f52SChris Cain 
1046f0295f52SChris Cain     // Set pointer to autodelete
1047f0295f52SChris Cain     std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{
1048f0295f52SChris Cain         responseMsg, std::free};
1049f0295f52SChris Cain 
1050f0295f52SChris Cain     auto response = reinterpret_cast<pldm_msg*>(responseMsgPtr.get());
1051f0295f52SChris Cain     if (response->payload[0] != PLDM_SUCCESS)
1052f0295f52SChris Cain     {
105337abe9beSChris Cain         lg2::error(
105437abe9beSChris Cain             "pldmResetCallback: Reset FAILED ({MSG}) - payload[0] was not success: {STATUS}",
105537abe9beSChris Cain             "MSG", msgType, "STATUS", response->payload[0]);
1056f0295f52SChris Cain         pldmIface->pldmClose();
1057f0295f52SChris Cain 
1058f0295f52SChris Cain         if (msgType == MSG_OCC_RESET)
1059f0295f52SChris Cain         {
1060f0295f52SChris Cain             // Retry reset request
106137abe9beSChris Cain             lg2::error(
106237abe9beSChris Cain                 "pldmResetCallback: retrying reset request for OCC{INST}",
106337abe9beSChris Cain                 "INST", resetInstance);
1064f0295f52SChris Cain             pldmIface->resetOCC(resetInstance);
1065f0295f52SChris Cain         }
1066f0295f52SChris Cain         return -1;
1067f0295f52SChris Cain     }
1068f0295f52SChris Cain     else
1069f0295f52SChris Cain     {
107037abe9beSChris Cain         lg2::info("pldmResetCallback: Reset has been successfully started");
1071f0295f52SChris Cain     }
1072f0295f52SChris Cain 
1073f0295f52SChris Cain     pldmIface->pldmClose();
1074f0295f52SChris Cain 
1075f0295f52SChris Cain     pldmIface->pldmResponseReceived = true;
1076f0295f52SChris Cain 
1077f0295f52SChris Cain     return 0;
1078f0295f52SChris Cain }
1079f0295f52SChris Cain 
encodeGetStateSensorRequest(uint8_t instance,uint16_t sensorId)10802d6ec909SPatrick Williams std::vector<uint8_t> Interface::encodeGetStateSensorRequest(uint8_t instance,
10812d6ec909SPatrick Williams                                                             uint16_t sensorId)
1082bae4d07eSChris Cain {
1083aeba51cdSRashmica Gupta     if (!getPldmInstanceId())
10848b508bfbSChris Cain     {
108537abe9beSChris Cain         lg2::error("encodeGetStateSensorRequest: failed to getPldmInstanceId");
10868b508bfbSChris Cain         return std::vector<uint8_t>();
10878b508bfbSChris Cain     }
10888b508bfbSChris Cain 
1089bae4d07eSChris Cain     bitfield8_t sRearm = {0};
1090d7542c83SPatrick Williams     const size_t msgSize =
1091d7542c83SPatrick Williams         sizeof(pldm_msg_hdr) + PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES;
1092bae4d07eSChris Cain     std::vector<uint8_t> request(msgSize);
10938b508bfbSChris Cain 
1094bae4d07eSChris Cain     auto msg = reinterpret_cast<pldm_msg*>(request.data());
1095aeba51cdSRashmica Gupta     auto msgRc = encode_get_state_sensor_readings_req(pldmInstanceID.value(),
10968b508bfbSChris Cain                                                       sensorId, sRearm, 0, msg);
1097bae4d07eSChris Cain     if (msgRc != PLDM_SUCCESS)
1098bae4d07eSChris Cain     {
109937abe9beSChris Cain         lg2::error(
110037abe9beSChris Cain             "encodeGetStateSensorRequest: Failed to encode sensorId:{ID} for OCC{INST} (rc={RC})",
110137abe9beSChris Cain             "ID", lg2::hex, sensorId, "INST", instance, "RC", msgRc);
1102d1b6826aSChris Cain     }
1103bae4d07eSChris Cain     return request;
1104bae4d07eSChris Cain }
1105bae4d07eSChris Cain 
1106bae4d07eSChris Cain // Initiate query of the specified OCC Active Sensor
checkActiveSensor(uint8_t instance)1107bae4d07eSChris Cain void Interface::checkActiveSensor(uint8_t instance)
1108bae4d07eSChris Cain {
1109bae4d07eSChris Cain     static bool tracedOnce = false;
1110bae4d07eSChris Cain     if (pldmFd > 0)
1111bae4d07eSChris Cain     {
1112755af102SChris Cain         if (!throttleTraces && !tracedOnce)
1113bae4d07eSChris Cain         {
111437abe9beSChris Cain             lg2::warning(
111537abe9beSChris Cain                 "checkActiveSensor: already waiting on OCC{INST} (fd={FD})",
111637abe9beSChris Cain                 "INST", pldmResponseOcc, "FD", pldmFd);
1117bae4d07eSChris Cain             tracedOnce = true;
1118bae4d07eSChris Cain         }
1119bae4d07eSChris Cain         return;
1120bae4d07eSChris Cain     }
1121bae4d07eSChris Cain     tracedOnce = false;
1122bae4d07eSChris Cain 
1123bae4d07eSChris Cain     if (!isOCCSensorCacheValid())
1124bae4d07eSChris Cain     {
1125bae4d07eSChris Cain         fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
1126bae4d07eSChris Cain                         sensorToOCCInstance, OCCSensorOffset);
1127bae4d07eSChris Cain     }
1128bae4d07eSChris Cain 
1129bae4d07eSChris Cain     // look up sensor id (key) based on instance
1130bae4d07eSChris Cain     auto entry = std::find_if(
1131bae4d07eSChris Cain         sensorToOCCInstance.begin(), sensorToOCCInstance.end(),
1132bae4d07eSChris Cain         [instance](const auto& entry) { return instance == entry.second; });
1133bae4d07eSChris Cain     if (entry != sensorToOCCInstance.end())
1134bae4d07eSChris Cain     {
1135bae4d07eSChris Cain         // Query the OCC Active Sensor state for this instance
1136755af102SChris Cain         if (!throttleTraces)
1137755af102SChris Cain         {
113837abe9beSChris Cain             lg2::info("checkActiveSensor: OCC{INST} / sensorID: {ID}", "INST",
113937abe9beSChris Cain                       instance, "ID", lg2::hex, entry->first);
1140755af102SChris Cain         }
1141bae4d07eSChris Cain 
1142bae4d07eSChris Cain         // Encode GetStateSensorReadings PLDM message
1143bae4d07eSChris Cain         auto request = encodeGetStateSensorRequest(instance, entry->first);
1144bae4d07eSChris Cain         if (request.empty())
1145bae4d07eSChris Cain         {
1146bae4d07eSChris Cain             return;
1147bae4d07eSChris Cain         }
1148bae4d07eSChris Cain 
1149bae4d07eSChris Cain         // Send request to PLDM and setup callback for response
1150f0295f52SChris Cain         msgType = MSG_SENSOR_STATUS;
1151bae4d07eSChris Cain         sendPldm(request, instance, true);
1152bae4d07eSChris Cain     }
1153bae4d07eSChris Cain     else
1154bae4d07eSChris Cain     {
1155755af102SChris Cain         if (!throttleTraces)
1156755af102SChris Cain         {
115737abe9beSChris Cain             lg2::error(
115837abe9beSChris Cain                 "checkActiveSensor: Unable to find PLDM sensor for OCC{INST}",
115937abe9beSChris Cain                 "INST", instance);
116037abe9beSChris Cain             lg2::info(
11618cf7496bSChris Cain                 "checkActiveSensor: fetching STATE_SET_OPERATIONAL_RUNNING_STATUS");
1162755af102SChris Cain         }
11638cf7496bSChris Cain         fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
11648cf7496bSChris Cain                         sensorToOCCInstance, OCCSensorOffset);
116500325238STom Joseph     }
116600325238STom Joseph }
116700325238STom Joseph 
setTraceThrottle(const bool throttle)1168755af102SChris Cain void Interface::setTraceThrottle(const bool throttle)
1169755af102SChris Cain {
1170755af102SChris Cain     if (throttle != throttleTraces)
1171755af102SChris Cain     {
1172755af102SChris Cain         if (throttle)
1173755af102SChris Cain         {
117437abe9beSChris Cain             lg2::warning("PLDM traces being throttled");
1175755af102SChris Cain         }
1176755af102SChris Cain         else
1177755af102SChris Cain         {
117837abe9beSChris Cain             lg2::info("PLDM traces no longer being throttled");
1179755af102SChris Cain         }
1180755af102SChris Cain         throttleTraces = throttle;
1181755af102SChris Cain     }
1182755af102SChris Cain }
1183755af102SChris Cain 
1184815f9f55STom Joseph } // namespace pldm
1185