blob: dc7a280b0ef0d04a012fb2f3b3bc6257623998d2 [file] [log] [blame]
Patrick Williams05e95592021-09-02 09:28:14 -05001#include "pldm.hpp"
2
3#include "file.hpp"
4
Patrick Williams05e95592021-09-02 09:28:14 -05005#include <libpldm/entity.h>
Andrew Jeffery97476a12024-06-19 21:07:29 +09306#include <libpldm/oem/ibm/state_set.h>
Patrick Williams05e95592021-09-02 09:28:14 -05007#include <libpldm/platform.h>
8#include <libpldm/state_set.h>
9
10#include <phosphor-logging/log.hpp>
Chris Cainbae4d072022-02-28 09:46:50 -060011#include <sdbusplus/bus.hpp>
12#include <sdeventplus/clock.hpp>
13#include <sdeventplus/exception.hpp>
14#include <sdeventplus/source/io.hpp>
15#include <sdeventplus/source/time.hpp>
16
17#include <algorithm>
Patrick Williams48002492024-02-13 21:43:32 -060018#include <format>
Patrick Williams05e95592021-09-02 09:28:14 -050019
20namespace pldm
21{
22
Patrick Williams05e95592021-09-02 09:28:14 -050023using namespace phosphor::logging;
24
Chris Cainbae4d072022-02-28 09:46:50 -060025using namespace sdeventplus;
26using namespace sdeventplus::source;
27constexpr auto clockId = sdeventplus::ClockId::RealTime;
28using Clock = sdeventplus::Clock<clockId>;
29using Timer = Time<clockId>;
Chris Cain755af102024-02-27 16:09:51 -060030bool Interface::throttleTraces = false;
Chris Cainbae4d072022-02-28 09:46:50 -060031
Eddie Jamescbad2192021-10-07 09:39:39 -050032void Interface::fetchSensorInfo(uint16_t stateSetId,
33 SensorToInstance& sensorInstanceMap,
34 SensorOffset& sensorOffset)
Patrick Williams05e95592021-09-02 09:28:14 -050035{
Eddie Jamescbad2192021-10-07 09:39:39 -050036 PdrList pdrs{};
Chris Cainbae4d072022-02-28 09:46:50 -060037 static bool tracedError = false;
Eddie Jamescbad2192021-10-07 09:39:39 -050038
39 auto& bus = open_power::occ::utils::getBus();
40 try
41 {
42 auto method = bus.new_method_call(
43 "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
44 "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
Chris Cainbae4d072022-02-28 09:46:50 -060045 method.append(tid, static_cast<uint16_t>(PLDM_ENTITY_PROC), stateSetId);
Eddie Jamescbad2192021-10-07 09:39:39 -050046
47 auto responseMsg = bus.call(method);
48 responseMsg.read(pdrs);
49 }
Patrick Williamsaf408082022-07-22 19:26:54 -050050 catch (const sdbusplus::exception_t& e)
Eddie Jamescbad2192021-10-07 09:39:39 -050051 {
Chris Cainbae4d072022-02-28 09:46:50 -060052 if (!tracedError)
53 {
54 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -060055 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -060056 "fetchSensorInfo: Failed to find stateSetID:{} PDR: {}",
57 stateSetId, e.what())
58 .c_str());
59 tracedError = true;
60 }
Eddie Jamescbad2192021-10-07 09:39:39 -050061 }
62
63 if (pdrs.empty())
64 {
Chris Cainbae4d072022-02-28 09:46:50 -060065 if (!tracedError)
66 {
67 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -060068 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -060069 "fetchSensorInfo: state sensor PDRs ({}) not present",
70 stateSetId)
71 .c_str());
72 tracedError = true;
73 }
Eddie Jamescbad2192021-10-07 09:39:39 -050074 return;
75 }
76
Chris Cainbae4d072022-02-28 09:46:50 -060077 // Found PDR
78 if (tracedError)
79 {
80 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -060081 std::format("fetchSensorInfo: found {} PDRs", pdrs.size()).c_str());
Chris Cainbae4d072022-02-28 09:46:50 -060082 tracedError = false;
83 }
84
Patrick Williams05e95592021-09-02 09:28:14 -050085 bool offsetFound = false;
George Liuf3a4a692021-12-28 13:59:51 +080086 auto stateSensorPDR =
Patrick Williams05e95592021-09-02 09:28:14 -050087 reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
George Liuf3a4a692021-12-28 13:59:51 +080088 auto possibleStatesPtr = stateSensorPDR->possible_states;
89 for (auto offset = 0; offset < stateSensorPDR->composite_sensor_count;
90 offset++)
Patrick Williams05e95592021-09-02 09:28:14 -050091 {
92 auto possibleStates =
93 reinterpret_cast<const state_sensor_possible_states*>(
94 possibleStatesPtr);
95
Eddie Jamescbad2192021-10-07 09:39:39 -050096 if (possibleStates->state_set_id == stateSetId)
Patrick Williams05e95592021-09-02 09:28:14 -050097 {
98 sensorOffset = offset;
99 offsetFound = true;
100 break;
101 }
102 possibleStatesPtr += sizeof(possibleStates->state_set_id) +
103 sizeof(possibleStates->possible_states_size) +
104 possibleStates->possible_states_size;
105 }
106
107 if (!offsetFound)
108 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500109 log<level::ERR>("pldm: state sensor PDR not found");
Patrick Williams05e95592021-09-02 09:28:14 -0500110 return;
111 }
112
113 // To order SensorID based on the EntityInstance.
114 // Note that when a proc is on a DCM, the PDRs for these sensors
115 // could have the same instance IDs but different container IDs.
116 std::map<uint32_t, SensorID> entityInstMap{};
117 for (auto& pdr : pdrs)
118 {
119 auto pdrPtr =
120 reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
Chris Cain72d01aa2022-06-14 16:28:03 -0500121 uint32_t key = pdrPtr->sensor_id;
Patrick Williams05e95592021-09-02 09:28:14 -0500122 entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->sensor_id));
123 }
124
125 open_power::occ::instanceID count = start;
Patrick Williamsa49c9872023-05-10 07:50:35 -0500126 for (const auto& pair : entityInstMap)
Patrick Williams05e95592021-09-02 09:28:14 -0500127 {
128 sensorInstanceMap.emplace(pair.second, count);
129 count++;
130 }
131}
132
Patrick Williamsaf408082022-07-22 19:26:54 -0500133void Interface::sensorEvent(sdbusplus::message_t& msg)
Patrick Williams05e95592021-09-02 09:28:14 -0500134{
135 if (!isOCCSensorCacheValid())
136 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500137 fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
138 sensorToOCCInstance, OCCSensorOffset);
139 }
Patrick Williams05e95592021-09-02 09:28:14 -0500140
Eddie Jamescbad2192021-10-07 09:39:39 -0500141 if (sensorToSBEInstance.empty())
142 {
143 fetchSensorInfo(PLDM_OEM_IBM_SBE_HRESET_STATE, sensorToSBEInstance,
144 SBESensorOffset);
Patrick Williams05e95592021-09-02 09:28:14 -0500145 }
146
Chris Cain72d01aa2022-06-14 16:28:03 -0500147 TerminusID sensorTid{};
Patrick Williams05e95592021-09-02 09:28:14 -0500148 SensorID sensorId{};
149 SensorOffset msgSensorOffset{};
150 EventState eventState{};
151 EventState previousEventState{};
152
Chris Cain72d01aa2022-06-14 16:28:03 -0500153 msg.read(sensorTid, sensorId, msgSensorOffset, eventState,
154 previousEventState);
Patrick Williams05e95592021-09-02 09:28:14 -0500155
Eddie Jamescbad2192021-10-07 09:39:39 -0500156 if (msgSensorOffset == OCCSensorOffset)
Patrick Williams05e95592021-09-02 09:28:14 -0500157 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500158 auto sensorEntry = sensorToOCCInstance.find(sensorId);
Patrick Williams05e95592021-09-02 09:28:14 -0500159
Eddie James432dc482021-11-19 15:29:31 -0600160 if (sensorEntry != sensorToOCCInstance.end())
Eddie Jamescbad2192021-10-07 09:39:39 -0500161 {
Chris Cain8b508bf2022-05-26 14:01:31 -0500162 const uint8_t instance = sensorEntry->second;
Chris Cain755af102024-02-27 16:09:51 -0600163 bool validEvent = true;
Chris Cain7b00cde2023-03-14 15:47:12 -0500164 bool isRunning = false;
Eddie James432dc482021-11-19 15:29:31 -0600165 if (eventState ==
166 static_cast<EventState>(
167 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
168 {
169 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600170 std::format("PLDM: OCC{} is RUNNING", instance).c_str());
Chris Cain7b00cde2023-03-14 15:47:12 -0500171 isRunning = true;
Eddie James432dc482021-11-19 15:29:31 -0600172 }
173 else if (eventState ==
174 static_cast<EventState>(
175 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
176 {
Chris Cain8b508bf2022-05-26 14:01:31 -0500177 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600178 std::format("PLDM: OCC{} has now STOPPED", instance)
Chris Cain8b508bf2022-05-26 14:01:31 -0500179 .c_str());
Eddie James432dc482021-11-19 15:29:31 -0600180 }
Chris Cainbae4d072022-02-28 09:46:50 -0600181 else if (eventState ==
182 static_cast<EventState>(
183 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT))
184 {
Chris Cain755af102024-02-27 16:09:51 -0600185 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600186 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600187 "PLDM: OCC{} has now STOPPED and system is in SAFE MODE",
Chris Cain8b508bf2022-05-26 14:01:31 -0500188 instance)
Chris Cainbae4d072022-02-28 09:46:50 -0600189 .c_str());
Sheldon Bailey31a2f132022-05-20 11:31:52 -0500190
191 // Setting safe mode true
192 safeModeCallBack(true);
Chris Cainbae4d072022-02-28 09:46:50 -0600193 }
194 else
195 {
Chris Cain755af102024-02-27 16:09:51 -0600196 log<level::WARNING>(
Patrick Williams48002492024-02-13 21:43:32 -0600197 std::format("PLDM: Unexpected PLDM state {} for OCC{}",
Chris Cain8b508bf2022-05-26 14:01:31 -0500198 eventState, instance)
Chris Cainbae4d072022-02-28 09:46:50 -0600199 .c_str());
Chris Cain755af102024-02-27 16:09:51 -0600200 validEvent = false;
Chris Cainbae4d072022-02-28 09:46:50 -0600201 }
Chris Cain755af102024-02-27 16:09:51 -0600202 if (validEvent)
203 {
204 if ((pldmFd > 0) && (instance == pldmResponseOcc))
205 {
206 // Waiting for a response for this OCC, can stop waiting
207 pldmClose();
208 }
209 callBack(instance, isRunning);
210 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500211 return;
212 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500213 }
Eddie James432dc482021-11-19 15:29:31 -0600214
215 if (msgSensorOffset == SBESensorOffset)
Eddie Jamescbad2192021-10-07 09:39:39 -0500216 {
217 auto sensorEntry = sensorToSBEInstance.find(sensorId);
218
Eddie James432dc482021-11-19 15:29:31 -0600219 if (sensorEntry != sensorToSBEInstance.end())
Eddie Jamescbad2192021-10-07 09:39:39 -0500220 {
Chris Cain12d0b822022-04-22 17:29:18 -0500221 const uint8_t instance = sensorEntry->second;
222 auto match = std::find(outstandingHResets.begin(),
223 outstandingHResets.end(), instance);
224 if (match != outstandingHResets.end())
Eddie James432dc482021-11-19 15:29:31 -0600225 {
Chris Cain12d0b822022-04-22 17:29:18 -0500226 outstandingHResets.erase(match);
227 if (eventState == static_cast<EventState>(SBE_HRESET_NOT_READY))
228 {
229 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600230 std::format("pldm: HRESET is NOT READY (OCC{})",
Chris Cain12d0b822022-04-22 17:29:18 -0500231 instance)
232 .c_str());
233 }
234 else if (eventState ==
235 static_cast<EventState>(SBE_HRESET_READY))
236 {
237 sbeCallBack(instance, true);
238 }
239 else if (eventState ==
240 static_cast<EventState>(SBE_HRESET_FAILED))
241 {
242 sbeCallBack(instance, false);
243 }
Eddie James432dc482021-11-19 15:29:31 -0600244 }
Chris Cain12d0b822022-04-22 17:29:18 -0500245 // else request was not from us
Eddie Jamescbad2192021-10-07 09:39:39 -0500246 }
247 }
Patrick Williams05e95592021-09-02 09:28:14 -0500248}
249
Patrick Williamsaf408082022-07-22 19:26:54 -0500250void Interface::hostStateEvent(sdbusplus::message_t& msg)
Chris Cain157467d2022-06-24 11:25:23 -0500251{
252 std::map<std::string, std::variant<std::string>> properties{};
253 std::string interface;
254 msg.read(interface, properties);
255 const auto stateEntry = properties.find("CurrentHostState");
256 if (stateEntry != properties.end())
257 {
258 auto stateEntryValue = stateEntry->second;
259 auto propVal = std::get<std::string>(stateEntryValue);
260 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
261 {
262 clearData();
263 }
264 }
265}
266
Chris Cainbae4d072022-02-28 09:46:50 -0600267void Interface::clearData()
268{
Chris Cain72d01aa2022-06-14 16:28:03 -0500269 if (!sensorToOCCInstance.empty())
270 {
271 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600272 std::format("clearData: Clearing sensorToOCCInstance ({} entries)",
Chris Cain72d01aa2022-06-14 16:28:03 -0500273 sensorToOCCInstance.size())
274 .c_str());
275 for (auto entry : sensorToOCCInstance)
276 {
277 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600278 std::format("clearData: OCC{} / sensorID: 0x{:04X}",
Chris Cain72d01aa2022-06-14 16:28:03 -0500279 entry.second, entry.first)
280 .c_str());
Chris Cain082a6ca2023-03-21 10:27:26 -0500281 callBack(entry.second, false);
Chris Cain72d01aa2022-06-14 16:28:03 -0500282 }
283 sensorToOCCInstance.clear();
284 }
285 if (!occInstanceToEffecter.empty())
286 {
287 log<level::DEBUG>(
Patrick Williams48002492024-02-13 21:43:32 -0600288 std::format(
Chris Cain72d01aa2022-06-14 16:28:03 -0500289 "clearData: Clearing occInstanceToEffecter ({} entries)",
290 occInstanceToEffecter.size())
291 .c_str());
292 occInstanceToEffecter.clear();
293 }
294 if (!sensorToSBEInstance.empty())
295 {
296 log<level::DEBUG>(
Patrick Williams48002492024-02-13 21:43:32 -0600297 std::format("clearData: Clearing sensorToSBEInstance ({} entries)",
Chris Cain72d01aa2022-06-14 16:28:03 -0500298 sensorToSBEInstance.size())
299 .c_str());
300 sensorToSBEInstance.clear();
301 }
302 if (!sbeInstanceToEffecter.empty())
303 {
304 log<level::DEBUG>(
Patrick Williams48002492024-02-13 21:43:32 -0600305 std::format(
Chris Cain72d01aa2022-06-14 16:28:03 -0500306 "clearData: Clearing sbeInstanceToEffecter ({} entries)",
307 sbeInstanceToEffecter.size())
308 .c_str());
309 sbeInstanceToEffecter.clear();
310 }
Chris Cainbae4d072022-02-28 09:46:50 -0600311}
312
Eddie James432dc482021-11-19 15:29:31 -0600313void Interface::fetchEffecterInfo(uint16_t stateSetId,
Eddie Jamescbad2192021-10-07 09:39:39 -0500314 InstanceToEffecter& instanceToEffecterMap,
315 CompositeEffecterCount& effecterCount,
316 uint8_t& stateIdPos)
Patrick Williams05e95592021-09-02 09:28:14 -0500317{
Eddie Jamescbad2192021-10-07 09:39:39 -0500318 PdrList pdrs{};
319
320 auto& bus = open_power::occ::utils::getBus();
321 try
322 {
323 auto method = bus.new_method_call(
324 "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
325 "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
Chris Cainbae4d072022-02-28 09:46:50 -0600326 method.append(tid, static_cast<uint16_t>(PLDM_ENTITY_PROC), stateSetId);
Eddie Jamescbad2192021-10-07 09:39:39 -0500327
328 auto responseMsg = bus.call(method);
329 responseMsg.read(pdrs);
330 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500331 catch (const sdbusplus::exception_t& e)
Eddie Jamescbad2192021-10-07 09:39:39 -0500332 {
333 log<level::ERR>("pldm: Failed to fetch the state effecter PDRs",
334 entry("ERROR=%s", e.what()));
335 }
336
337 if (!pdrs.size())
338 {
339 log<level::ERR>("pldm: state effecter PDRs not present");
340 return;
341 }
342
Patrick Williams05e95592021-09-02 09:28:14 -0500343 bool offsetFound = false;
George Liuf3a4a692021-12-28 13:59:51 +0800344 auto stateEffecterPDR =
Patrick Williams05e95592021-09-02 09:28:14 -0500345 reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
George Liuf3a4a692021-12-28 13:59:51 +0800346 auto possibleStatesPtr = stateEffecterPDR->possible_states;
347 for (auto offset = 0; offset < stateEffecterPDR->composite_effecter_count;
348 offset++)
Patrick Williams05e95592021-09-02 09:28:14 -0500349 {
350 auto possibleStates =
351 reinterpret_cast<const state_effecter_possible_states*>(
352 possibleStatesPtr);
353
Eddie Jamescbad2192021-10-07 09:39:39 -0500354 if (possibleStates->state_set_id == stateSetId)
Patrick Williams05e95592021-09-02 09:28:14 -0500355 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500356 stateIdPos = offset;
George Liuf3a4a692021-12-28 13:59:51 +0800357 effecterCount = stateEffecterPDR->composite_effecter_count;
Patrick Williams05e95592021-09-02 09:28:14 -0500358 offsetFound = true;
359 break;
360 }
361 possibleStatesPtr += sizeof(possibleStates->state_set_id) +
362 sizeof(possibleStates->possible_states_size) +
363 possibleStates->possible_states_size;
364 }
365
366 if (!offsetFound)
367 {
368 return;
369 }
370
Chris Cain0f516522022-02-07 14:48:28 -0600371 std::map<uint32_t, EffecterID> entityInstMap{};
Patrick Williams05e95592021-09-02 09:28:14 -0500372 for (auto& pdr : pdrs)
373 {
374 auto pdrPtr =
375 reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
Chris Cain72d01aa2022-06-14 16:28:03 -0500376 uint32_t key = pdrPtr->effecter_id;
Patrick Williams05e95592021-09-02 09:28:14 -0500377 entityInstMap.emplace(key, static_cast<SensorID>(pdrPtr->effecter_id));
378 }
379
380 open_power::occ::instanceID position = start;
Patrick Williamsa49c9872023-05-10 07:50:35 -0500381 for (const auto& pair : entityInstMap)
Patrick Williams05e95592021-09-02 09:28:14 -0500382 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500383 instanceToEffecterMap.emplace(position, pair.second);
Patrick Williams05e95592021-09-02 09:28:14 -0500384 position++;
385 }
386}
387
388std::vector<uint8_t>
Chris Cain8b508bf2022-05-26 14:01:31 -0500389 Interface::prepareSetEffecterReq(EffecterID effecterId,
Patrick Williams05e95592021-09-02 09:28:14 -0500390 CompositeEffecterCount effecterCount,
Eddie Jamescbad2192021-10-07 09:39:39 -0500391 uint8_t stateIdPos, uint8_t stateSetValue)
Patrick Williams05e95592021-09-02 09:28:14 -0500392{
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100393 if (!getPldmInstanceId())
Chris Cain8b508bf2022-05-26 14:01:31 -0500394 {
395 return std::vector<uint8_t>();
396 }
397
Patrick Williams05e95592021-09-02 09:28:14 -0500398 std::vector<uint8_t> request(
399 sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
400 (effecterCount * sizeof(set_effecter_state_field)));
401 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
402 std::vector<set_effecter_state_field> stateField;
403
404 for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
405 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500406 if (effecterPos == stateIdPos)
Patrick Williams05e95592021-09-02 09:28:14 -0500407 {
Eddie Jamescbad2192021-10-07 09:39:39 -0500408 stateField.emplace_back(
409 set_effecter_state_field{PLDM_REQUEST_SET, stateSetValue});
Patrick Williams05e95592021-09-02 09:28:14 -0500410 }
411 else
412 {
413 stateField.emplace_back(
414 set_effecter_state_field{PLDM_NO_CHANGE, 0});
415 }
416 }
417 auto rc = encode_set_state_effecter_states_req(
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100418 pldmInstanceID.value(), effecterId, effecterCount, stateField.data(),
Chris Cain8b508bf2022-05-26 14:01:31 -0500419 requestMsg);
Patrick Williams05e95592021-09-02 09:28:14 -0500420 if (rc != PLDM_SUCCESS)
421 {
422 log<level::ERR>("encode set effecter states request returned error ",
423 entry("RC=%d", rc));
424 request.clear();
425 }
426 return request;
427}
428
429void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
430{
Chris Cainbae4d072022-02-28 09:46:50 -0600431 if (open_power::occ::utils::isHostRunning())
Patrick Williams05e95592021-09-02 09:28:14 -0500432 {
Chris Cainbae4d072022-02-28 09:46:50 -0600433 if (!isPDREffecterCacheValid())
434 {
435 fetchEffecterInfo(PLDM_STATE_SET_BOOT_RESTART_CAUSE,
436 occInstanceToEffecter, OCCEffecterCount,
437 bootRestartPosition);
438 }
Patrick Williams05e95592021-09-02 09:28:14 -0500439
Chris Cainbae4d072022-02-28 09:46:50 -0600440 // Find the matching effecter for the OCC instance
441 auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
442 if (effecterEntry == occInstanceToEffecter.end())
443 {
444 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600445 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600446 "pldm: Failed to find a matching effecter for OCC instance {}",
447 occInstanceId)
448 .c_str());
449
450 return;
451 }
452
Chris Cainbae4d072022-02-28 09:46:50 -0600453 // Prepare the SetStateEffecterStates request to reset the OCC
454 auto request = prepareSetEffecterReq(
Chris Cain8b508bf2022-05-26 14:01:31 -0500455 effecterEntry->second, OCCEffecterCount, bootRestartPosition,
456 PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET);
Chris Cainbae4d072022-02-28 09:46:50 -0600457
458 if (request.empty())
459 {
460 log<level::ERR>(
461 "pldm: SetStateEffecterStates OCC reset request empty");
462 return;
463 }
464
465 // Send request to reset the OCCs/PM Complex (ignore response)
466 sendPldm(request, occInstanceId, false);
467 }
468 else
Patrick Williams05e95592021-09-02 09:28:14 -0500469 {
470 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600471 std::format("resetOCC: HOST is not running (OCC{})", occInstanceId)
Chris Cain0f516522022-02-07 14:48:28 -0600472 .c_str());
Chris Cainbae4d072022-02-28 09:46:50 -0600473 clearData();
Patrick Williams05e95592021-09-02 09:28:14 -0500474 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500475}
476
477void Interface::sendHRESET(open_power::occ::instanceID sbeInstanceId)
478{
Chris Cainbae4d072022-02-28 09:46:50 -0600479 if (open_power::occ::utils::isHostRunning())
Eddie Jamescbad2192021-10-07 09:39:39 -0500480 {
Chris Cainbae4d072022-02-28 09:46:50 -0600481 if (sbeInstanceToEffecter.empty())
482 {
483 fetchEffecterInfo(PLDM_OEM_IBM_SBE_MAINTENANCE_STATE,
484 sbeInstanceToEffecter, SBEEffecterCount,
485 sbeMaintenanceStatePosition);
486 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500487
Chris Cainbae4d072022-02-28 09:46:50 -0600488 auto effecterEntry = sbeInstanceToEffecter.find(sbeInstanceId);
489 if (effecterEntry == sbeInstanceToEffecter.end())
490 {
491 log<level::ERR>(
492 "pldm: Failed to find a matching effecter for SBE instance",
493 entry("SBE=%d", sbeInstanceId));
494 return;
495 }
496
Chris Cainbae4d072022-02-28 09:46:50 -0600497 // Prepare the SetStateEffecterStates request to HRESET the SBE
498 auto request = prepareSetEffecterReq(
Chris Cain8b508bf2022-05-26 14:01:31 -0500499 effecterEntry->second, SBEEffecterCount,
Chris Cainbae4d072022-02-28 09:46:50 -0600500 sbeMaintenanceStatePosition, SBE_RETRY_REQUIRED);
501
502 if (request.empty())
503 {
504 log<level::ERR>(
505 "pldm: SetStateEffecterStates HRESET request empty");
506 return;
507 }
508
509 // Send request to issue HRESET of SBE (ignore response)
510 sendPldm(request, sbeInstanceId, false);
Chris Cain12d0b822022-04-22 17:29:18 -0500511 outstandingHResets.insert(sbeInstanceId);
Chris Cainbae4d072022-02-28 09:46:50 -0600512 }
513 else
Eddie Jamescbad2192021-10-07 09:39:39 -0500514 {
Patrick Williams48002492024-02-13 21:43:32 -0600515 log<level::ERR>(std::format("sendHRESET: HOST is not running (OCC{})",
Chris Cainbae4d072022-02-28 09:46:50 -0600516 sbeInstanceId)
517 .c_str());
518 clearData();
Eddie Jamescbad2192021-10-07 09:39:39 -0500519 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500520}
521
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100522bool Interface::getPldmInstanceId()
Eddie Jamescbad2192021-10-07 09:39:39 -0500523{
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100524 if (!pldmInstanceID)
Patrick Williams05e95592021-09-02 09:28:14 -0500525 {
Chris Cain8b508bf2022-05-26 14:01:31 -0500526 // Request new instance ID
527 auto& bus = open_power::occ::utils::getBus();
528 try
529 {
530 auto method = bus.new_method_call(
531 "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
532 "xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
533 method.append(mctpEid);
534 auto reply = bus.call(method);
535 uint8_t newInstanceId;
536 reply.read(newInstanceId);
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100537 pldmInstanceID = newInstanceId;
Chris Cain755af102024-02-27 16:09:51 -0600538 if (!throttleTraces)
539 {
540 log<level::INFO>(std::format("pldm: got new InstanceId: {}",
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100541 pldmInstanceID.value())
Chris Cain755af102024-02-27 16:09:51 -0600542 .c_str());
543 }
Chris Cain8b508bf2022-05-26 14:01:31 -0500544 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500545 catch (const sdbusplus::exception_t& e)
Chris Cain8b508bf2022-05-26 14:01:31 -0500546 {
547 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600548 std::format("pldm: GetInstanceId failed: {}", e.what())
Chris Cain8b508bf2022-05-26 14:01:31 -0500549 .c_str());
550 return false;
551 }
Patrick Williams05e95592021-09-02 09:28:14 -0500552 }
553
Eddie Jamescbad2192021-10-07 09:39:39 -0500554 return true;
555}
Patrick Williams05e95592021-09-02 09:28:14 -0500556
Chris Cainbae4d072022-02-28 09:46:50 -0600557void Interface::sendPldm(const std::vector<uint8_t>& request,
558 const uint8_t instance, const bool rspExpected)
Eddie Jamescbad2192021-10-07 09:39:39 -0500559{
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100560 if (!pldmInstanceID)
Chris Cain8b508bf2022-05-26 14:01:31 -0500561 {
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100562 log<level::ERR>("sendPldm: No PLDM Instance ID found!");
Chris Cain8b508bf2022-05-26 14:01:31 -0500563 return;
564 }
565
Chris Cainc9dc4412023-03-06 15:56:34 -0600566 // Connect to MCTP socket
Chris Cainbae4d072022-02-28 09:46:50 -0600567 pldmFd = pldm_open();
568 auto openErrno = errno;
569 if (pldmFd == PLDM_REQUESTER_OPEN_FAIL)
Patrick Williams05e95592021-09-02 09:28:14 -0500570 {
Chris Caind1b68262022-02-28 09:56:50 -0600571 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600572 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600573 "sendPldm: Failed to connect to MCTP socket, errno={}/{}",
574 openErrno, strerror(openErrno))
Chris Caind1b68262022-02-28 09:56:50 -0600575 .c_str());
Patrick Williams05e95592021-09-02 09:28:14 -0500576 return;
577 }
Eddie Jamescbad2192021-10-07 09:39:39 -0500578
Patrick Williams05e95592021-09-02 09:28:14 -0500579 // Send the PLDM request message to HBRT
Chris Cainbae4d072022-02-28 09:46:50 -0600580 if (rspExpected)
Patrick Williams05e95592021-09-02 09:28:14 -0500581 {
Chris Cainbae4d072022-02-28 09:46:50 -0600582 // Register callback when response is available
583 registerPldmRspCallback();
584
585 // Send PLDM request
Chris Cain755af102024-02-27 16:09:51 -0600586 if (!throttleTraces)
587 {
588 log<level::INFO>(
589 std::format(
590 "sendPldm: calling pldm_send(OCC{}, instance:{}, {} bytes)",
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100591 instance, pldmInstanceID.value(), request.size())
Chris Cain755af102024-02-27 16:09:51 -0600592 .c_str());
593 }
Chris Cainbae4d072022-02-28 09:46:50 -0600594 pldmResponseReceived = false;
595 pldmResponseTimeout = false;
596 pldmResponseOcc = instance;
Patrick Williamsa49c9872023-05-10 07:50:35 -0500597 auto pldmRc = pldm_send(mctpEid, pldmFd, request.data(),
598 request.size());
Chris Cainbae4d072022-02-28 09:46:50 -0600599 auto sendErrno = errno;
600 if (pldmRc != PLDM_REQUESTER_SUCCESS)
601 {
602 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600603 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600604 "sendPldm: pldm_send failed with rc={} and errno={}/{}",
Chris Cain5161a022023-08-15 10:07:12 -0500605 static_cast<
606 std::underlying_type_t<pldm_requester_error_codes>>(
607 pldmRc),
608 sendErrno, strerror(sendErrno))
Chris Cainbae4d072022-02-28 09:46:50 -0600609 .c_str());
610 pldmClose();
611 return;
612 }
613
614 // start timer waiting for the response
615 using namespace std::literals::chrono_literals;
Chris Cainbd551de2022-04-26 13:41:16 -0500616 pldmRspTimer.restartOnce(8s);
Chris Cainbae4d072022-02-28 09:46:50 -0600617
618 // Wait for response/timeout
619 }
620 else // not expecting the response
621 {
Chris Cain755af102024-02-27 16:09:51 -0600622 if (!throttleTraces)
623 {
624 log<level::INFO>(
625 std::format(
626 "sendPldm: calling pldm_send(mctpID:{}, fd:{}, {} bytes) for OCC{}",
627 mctpEid, pldmFd, request.size(), instance)
628 .c_str());
629 }
Chris Cainbae4d072022-02-28 09:46:50 -0600630 auto rc = pldm_send(mctpEid, pldmFd, request.data(), request.size());
631 auto sendErrno = errno;
Chris Caind1b68262022-02-28 09:56:50 -0600632 if (rc)
633 {
634 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600635 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600636 "sendPldm: pldm_send(mctpID:{}, fd:{}, {} bytes) failed with rc={} and errno={}/{}",
Chris Cain5161a022023-08-15 10:07:12 -0500637 mctpEid, pldmFd, request.size(),
638 static_cast<
639 std::underlying_type_t<pldm_requester_error_codes>>(rc),
640 sendErrno, strerror(sendErrno))
Chris Caind1b68262022-02-28 09:56:50 -0600641 .c_str());
642 }
Chris Cain8b508bf2022-05-26 14:01:31 -0500643 else
644 {
645 // Not waiting for response, instance ID should be freed
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100646 pldmInstanceID = std::nullopt;
Chris Cain8b508bf2022-05-26 14:01:31 -0500647 }
Chris Cainbae4d072022-02-28 09:46:50 -0600648 pldmClose();
649 }
650}
Patrick Williams05e95592021-09-02 09:28:14 -0500651
Chris Cainbae4d072022-02-28 09:46:50 -0600652// Attaches the FD to event loop and registers the callback handler
653void Interface::registerPldmRspCallback()
654{
655 decltype(eventSource.get()) sourcePtr = nullptr;
656 auto rc = sd_event_add_io(event.get(), &sourcePtr, pldmFd, EPOLLIN,
657 pldmRspCallback, this);
658 if (rc < 0)
659 {
660 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600661 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600662 "registerPldmRspCallback: sd_event_add_io: Error({})={} : fd={}",
663 rc, strerror(-rc), pldmFd)
664 .c_str());
Chris Caind1b68262022-02-28 09:56:50 -0600665 }
666 else
Patrick Williams05e95592021-09-02 09:28:14 -0500667 {
Chris Cainbae4d072022-02-28 09:46:50 -0600668 // puts sourcePtr in the event source.
669 eventSource.reset(sourcePtr);
670 }
671}
672
673// Add a timer to the event loop, default 30s.
674void Interface::pldmRspExpired()
675{
676 if (!pldmResponseReceived)
677 {
Chris Cain755af102024-02-27 16:09:51 -0600678 if (!throttleTraces)
679 {
680 log<level::WARNING>(
681 std::format(
682 "pldmRspExpired: timerCallback - timeout waiting for pldm response for OCC{}",
683 pldmResponseOcc)
684 .c_str());
685 }
Chris Cainbae4d072022-02-28 09:46:50 -0600686 pldmResponseTimeout = true;
687 if (pldmFd)
688 {
689 pldmClose();
690 }
691 }
692 return;
693};
694
695void Interface::pldmClose()
696{
697 if (pldmRspTimer.isEnabled())
698 {
699 // stop PLDM response timer
700 pldmRspTimer.setEnabled(false);
701 }
Pavithra Barithaya159a2272023-09-27 06:10:55 -0500702 pldm_close();
Chris Cainbae4d072022-02-28 09:46:50 -0600703 pldmFd = -1;
704 eventSource.reset();
705}
706
707int Interface::pldmRspCallback(sd_event_source* /*es*/, int fd,
708 uint32_t revents, void* userData)
709{
710 if (!(revents & EPOLLIN))
711 {
712 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600713 std::format("pldmRspCallback - revents={:08X}", revents).c_str());
Chris Cainbae4d072022-02-28 09:46:50 -0600714 return -1;
715 }
716
717 auto pldmIface = static_cast<Interface*>(userData);
718
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100719 if (!pldmIface->pldmInstanceID)
Chris Cain8b508bf2022-05-26 14:01:31 -0500720 {
721 log<level::ERR>(
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100722 "pldmRspCallback: No outstanding PLDM Instance ID found");
Chris Cain8b508bf2022-05-26 14:01:31 -0500723 return -1;
724 }
725
Chris Cainbae4d072022-02-28 09:46:50 -0600726 uint8_t* responseMsg = nullptr;
727 size_t responseMsgSize{};
728
Chris Cain755af102024-02-27 16:09:51 -0600729 if (!throttleTraces)
730 {
731 log<level::INFO>(
732 std::format("pldmRspCallback: calling pldm_recv() instance:{}",
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100733 pldmIface->pldmInstanceID.value())
Chris Cain755af102024-02-27 16:09:51 -0600734 .c_str());
735 }
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100736 auto rc = pldm_recv(mctpEid, fd, pldmIface->pldmInstanceID.value(),
Chris Cain8b508bf2022-05-26 14:01:31 -0500737 &responseMsg, &responseMsgSize);
Chris Cainbae4d072022-02-28 09:46:50 -0600738 int lastErrno = errno;
739 if (rc)
740 {
Chris Cain755af102024-02-27 16:09:51 -0600741 if (!throttleTraces)
742 {
743 log<level::ERR>(
744 std::format(
745 "pldmRspCallback: pldm_recv failed with rc={}, errno={}/{}",
746 static_cast<
747 std::underlying_type_t<pldm_requester_error_codes>>(rc),
748 lastErrno, strerror(lastErrno))
749 .c_str());
750 }
Chris Cainbae4d072022-02-28 09:46:50 -0600751 return -1;
752 }
Chris Cain8b508bf2022-05-26 14:01:31 -0500753
754 // We got the response for the PLDM request msg that was sent
Chris Cain755af102024-02-27 16:09:51 -0600755 if (!throttleTraces)
756 {
757 log<level::INFO>(
758 std::format("pldmRspCallback: pldm_recv() rsp was {} bytes",
759 responseMsgSize)
760 .c_str());
761 }
Chris Cainbae4d072022-02-28 09:46:50 -0600762
763 if (pldmIface->pldmRspTimer.isEnabled())
764 {
765 // stop PLDM response timer
766 pldmIface->pldmRspTimer.setEnabled(false);
767 }
768
Chris Cain8b508bf2022-05-26 14:01:31 -0500769 // instance ID should be freed
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100770 pldmIface->pldmInstanceID = std::nullopt;
Chris Cain8b508bf2022-05-26 14:01:31 -0500771
Chris Cainbae4d072022-02-28 09:46:50 -0600772 // Set pointer to autodelete
773 std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
774 std::free};
775
Chris Cainbae4d072022-02-28 09:46:50 -0600776 auto response = reinterpret_cast<pldm_msg*>(responseMsgPtr.get());
777 if (response->payload[0] != PLDM_SUCCESS)
778 {
779 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600780 std::format("pldmRspCallback: payload[0] was not success: {}",
Chris Cainbae4d072022-02-28 09:46:50 -0600781 response->payload[0])
782 .c_str());
783 pldmIface->pldmClose();
784 return -1;
785 }
786
787 // Decode the response
788 uint8_t compCode = 0, sensorCount = 1;
789 get_sensor_state_field field[6];
790 responseMsgSize -= sizeof(pldm_msg_hdr);
791 auto msgRc = decode_get_state_sensor_readings_resp(
792 response, responseMsgSize, &compCode, &sensorCount, field);
793 if ((msgRc != PLDM_SUCCESS) || (compCode != PLDM_SUCCESS))
794 {
795 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600796 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600797 "pldmRspCallback: decode_get_state_sensor_readings failed with rc={} and compCode={}",
798 msgRc, compCode)
799 .c_str());
800 pldmIface->pldmClose();
801 return -1;
802 }
803
804 pldmIface->pldmClose();
805
806 const uint8_t instance = pldmIface->pldmResponseOcc;
807 const uint8_t occSensorState = field[0].present_state;
808 pldmIface->pldmResponseReceived = true;
809
810 if (occSensorState == PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE)
811 {
812 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600813 std::format("pldmRspCallback: OCC{} is RUNNING", instance).c_str());
Chris Cainbae4d072022-02-28 09:46:50 -0600814 pldmIface->callBack(instance, true);
815 }
Chris Cain733b2012022-05-04 11:54:06 -0500816 else if (occSensorState ==
817 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT)
818 {
Chris Cain755af102024-02-27 16:09:51 -0600819 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600820 std::format(
Chris Cain733b2012022-05-04 11:54:06 -0500821 "pldmRspCallback: OCC{} has now STOPPED and system is in SAFE MODE",
822 instance)
823 .c_str());
Sheldon Bailey31a2f132022-05-20 11:31:52 -0500824
825 // Setting safe mode true
826 pldmIface->safeModeCallBack(true);
827
Chris Cain733b2012022-05-04 11:54:06 -0500828 pldmIface->callBack(instance, false);
829 }
Chris Cain755af102024-02-27 16:09:51 -0600830 else if (occSensorState ==
831 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED)
Chris Cainbae4d072022-02-28 09:46:50 -0600832 {
833 log<level::INFO>(
Chris Cain755af102024-02-27 16:09:51 -0600834 std::format("pldmRspCallback: OCC{} is not running", instance)
Chris Cainbae4d072022-02-28 09:46:50 -0600835 .c_str());
Chris Cain755af102024-02-27 16:09:51 -0600836 pldmIface->callBack(instance, false);
837 }
838 else
839 {
840 const size_t rspLength = responseMsgSize + sizeof(pldm_msg_hdr);
841 std::vector<std::uint8_t> pldmResponse(rspLength);
842 memcpy(&pldmResponse[0], reinterpret_cast<std::uint8_t*>(response),
843 rspLength);
844 if (!throttleTraces)
Chris Cainc9dc4412023-03-06 15:56:34 -0600845 {
Chris Cain755af102024-02-27 16:09:51 -0600846 log<level::WARNING>(
Patrick Williams48002492024-02-13 21:43:32 -0600847 std::format(
Chris Cain755af102024-02-27 16:09:51 -0600848 "pldmRspCallback: Unexpected State: {} - PLDM response ({} bytes) for OCC{}:",
849 occSensorState, rspLength, instance)
Chris Cainc9dc4412023-03-06 15:56:34 -0600850 .c_str());
851 dump_hex(pldmResponse);
852 }
Chris Cainbae4d072022-02-28 09:46:50 -0600853 }
854
855 return 0;
856};
857
858std::vector<uint8_t> Interface::encodeGetStateSensorRequest(uint8_t instance,
859 uint16_t sensorId)
860{
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100861 if (!getPldmInstanceId())
Chris Cain8b508bf2022-05-26 14:01:31 -0500862 {
863 log<level::ERR>(
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100864 "encodeGetStateSensorRequest: failed to getPldmInstanceId");
Chris Cain8b508bf2022-05-26 14:01:31 -0500865 return std::vector<uint8_t>();
866 }
867
Chris Cainbae4d072022-02-28 09:46:50 -0600868 bitfield8_t sRearm = {0};
Patrick Williamsa49c9872023-05-10 07:50:35 -0500869 const size_t msgSize = sizeof(pldm_msg_hdr) +
870 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES;
Chris Cainbae4d072022-02-28 09:46:50 -0600871 std::vector<uint8_t> request(msgSize);
Chris Cain8b508bf2022-05-26 14:01:31 -0500872
Chris Cainbae4d072022-02-28 09:46:50 -0600873 auto msg = reinterpret_cast<pldm_msg*>(request.data());
Rashmica Guptaaeba51c2023-02-17 12:30:46 +1100874 auto msgRc = encode_get_state_sensor_readings_req(pldmInstanceID.value(),
Chris Cain8b508bf2022-05-26 14:01:31 -0500875 sensorId, sRearm, 0, msg);
Chris Cainbae4d072022-02-28 09:46:50 -0600876 if (msgRc != PLDM_SUCCESS)
877 {
878 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600879 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600880 "encodeGetStateSensorRequest: Failed to encode sensorId:0x{:08X} for OCC{} (rc={})",
881 sensorId, instance, msgRc)
882 .c_str());
883 }
884 return request;
885}
886
887// Initiate query of the specified OCC Active Sensor
888void Interface::checkActiveSensor(uint8_t instance)
889{
890 static bool tracedOnce = false;
891 if (pldmFd > 0)
892 {
Chris Cain755af102024-02-27 16:09:51 -0600893 if (!throttleTraces && !tracedOnce)
Chris Caind1b68262022-02-28 09:56:50 -0600894 {
Chris Cain755af102024-02-27 16:09:51 -0600895 log<level::WARNING>(
Patrick Williams48002492024-02-13 21:43:32 -0600896 std::format(
Chris Cainbae4d072022-02-28 09:46:50 -0600897 "checkActiveSensor: already waiting on OCC{} (fd={})",
898 pldmResponseOcc, pldmFd)
Chris Caind1b68262022-02-28 09:56:50 -0600899 .c_str());
Chris Cainbae4d072022-02-28 09:46:50 -0600900 tracedOnce = true;
Chris Caind1b68262022-02-28 09:56:50 -0600901 }
Chris Cainbae4d072022-02-28 09:46:50 -0600902 return;
903 }
904 tracedOnce = false;
905
906 if (!isOCCSensorCacheValid())
907 {
908 fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
909 sensorToOCCInstance, OCCSensorOffset);
910 }
911
912 // look up sensor id (key) based on instance
913 auto entry = std::find_if(
914 sensorToOCCInstance.begin(), sensorToOCCInstance.end(),
915 [instance](const auto& entry) { return instance == entry.second; });
916 if (entry != sensorToOCCInstance.end())
917 {
918 // Query the OCC Active Sensor state for this instance
Chris Cain755af102024-02-27 16:09:51 -0600919 if (!throttleTraces)
920 {
921 log<level::INFO>(
922 std::format("checkActiveSensor: OCC{} / sensorID: 0x{:04X}",
923 instance, entry->first)
924 .c_str());
925 }
Chris Cainbae4d072022-02-28 09:46:50 -0600926
Chris Cainbae4d072022-02-28 09:46:50 -0600927 // Encode GetStateSensorReadings PLDM message
928 auto request = encodeGetStateSensorRequest(instance, entry->first);
929 if (request.empty())
930 {
931 return;
932 }
933
934 // Send request to PLDM and setup callback for response
935 sendPldm(request, instance, true);
936 }
937 else
938 {
Chris Cain755af102024-02-27 16:09:51 -0600939 if (!throttleTraces)
940 {
941 log<level::ERR>(
942 std::format(
943 "checkActiveSensor: Unable to find PLDM sensor for OCC{}",
944 instance)
945 .c_str());
946 log<level::INFO>(
947 "checkActiveSensor: fetching STATE_SET_OPERATIONAL_RUNNING_STATUS");
948 }
Chris Cain8cf74962022-06-29 08:45:16 -0500949 fetchSensorInfo(PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
950 sensorToOCCInstance, OCCSensorOffset);
Patrick Williams05e95592021-09-02 09:28:14 -0500951 }
Patrick Williams05e95592021-09-02 09:28:14 -0500952}
953
Chris Cain755af102024-02-27 16:09:51 -0600954void Interface::setTraceThrottle(const bool throttle)
955{
956 if (throttle != throttleTraces)
957 {
958 if (throttle)
959 {
960 log<level::WARNING>("PLDM traces being throttled");
961 }
962 else
963 {
964 log<level::INFO>("PLDM traces no longer being throttled");
965 }
966 throttleTraces = throttle;
967 }
968}
969
Patrick Williams05e95592021-09-02 09:28:14 -0500970} // namespace pldm