blob: 679f3b54389aad407f665a57429f49e5ac956c59 [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301#include "platform.hpp"
2
Tom Josephb70a1962020-07-13 12:56:31 +05303#include "common/types.hpp"
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05004#include "common/utils.hpp"
Tom Josephc4959c32020-04-20 19:50:16 +05305#include "event_parser.hpp"
Sampa Misra12afe112020-05-25 11:40:44 -05006#include "pdr.hpp"
George Liu456c9a22020-01-13 11:36:22 +08007#include "pdr_numeric_effecter.hpp"
George Liua2870722020-02-11 11:09:30 +08008#include "pdr_state_effecter.hpp"
George Liuadbe1722020-05-09 19:20:19 +08009#include "pdr_state_sensor.hpp"
George Liu362c18d2020-05-14 09:46:36 +080010#include "pdr_utils.hpp"
George Liueccb0c52020-01-14 11:09:56 +080011#include "platform_numeric_effecter.hpp"
George Liu0d7aca82020-03-30 15:01:36 +080012#include "platform_state_effecter.hpp"
George Liu362c18d2020-05-14 09:46:36 +080013#include "platform_state_sensor.hpp"
George Liu83409572019-12-24 18:42:54 +080014
Manojkiran Edacc5f1582021-09-29 17:03:06 +053015#include <config.h>
George Liuc453e162022-12-21 17:16:23 +080016#include <libpldm/entity.h>
17#include <libpldm/state_set.h>
Manojkiran Edacc5f1582021-09-29 17:03:06 +053018
Riya Dixit49cfb132023-03-02 04:26:53 -060019#include <phosphor-logging/lg2.hpp>
20
21PHOSPHOR_LOG2_USING;
22
Brad Bishop5079ac42021-08-19 18:35:06 -040023using namespace pldm::utils;
24using namespace pldm::responder::pdr;
25using namespace pldm::responder::pdr_utils;
26
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053027namespace pldm
28{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053029namespace responder
30{
Sampa Misraa2fa0702019-05-31 01:28:55 -050031namespace platform
32{
Deepak Kodihallic682fe22020-03-04 00:42:54 -060033using InternalFailure =
34 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
35
George Liu1ec85d42020-02-12 16:05:32 +080036static const Json empty{};
37
George Liua2870722020-02-11 11:09:30 +080038void Handler::addDbusObjMaps(
George Liuadbe1722020-05-09 19:20:19 +080039 uint16_t id,
40 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
41 TypeId typeId)
George Liu1ec85d42020-02-12 16:05:32 +080042{
George Liuadbe1722020-05-09 19:20:19 +080043 if (typeId == TypeId::PLDM_SENSOR_ID)
44 {
45 sensorDbusObjMaps.emplace(id, dbusObj);
46 }
47 else
48 {
49 effecterDbusObjMaps.emplace(id, dbusObj);
50 }
George Liu1ec85d42020-02-12 16:05:32 +080051}
52
George Liua2870722020-02-11 11:09:30 +080053const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liuadbe1722020-05-09 19:20:19 +080054 Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
George Liu1ec85d42020-02-12 16:05:32 +080055{
George Liuadbe1722020-05-09 19:20:19 +080056 if (typeId == TypeId::PLDM_SENSOR_ID)
57 {
58 return sensorDbusObjMaps.at(id);
59 }
60 else
61 {
62 return effecterDbusObjMaps.at(id);
63 }
George Liu1ec85d42020-02-12 16:05:32 +080064}
65
George Liu36e81352020-07-01 14:40:30 +080066void Handler::generate(const pldm::utils::DBusHandler& dBusIntf,
67 const std::string& dir, Repo& repo)
Deepak Kodihallic682fe22020-03-04 00:42:54 -060068{
Deepak Kodihallic6e49c42020-07-01 03:39:27 -050069 if (!fs::exists(dir))
70 {
71 return;
72 }
73
Deepak Kodihallic682fe22020-03-04 00:42:54 -060074 // A map of PDR type to a lambda that handles creation of that PDR type.
75 // The lambda essentially would parse the platform specific PDR JSONs to
76 // generate the PDR structures. This function iterates through the map to
77 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080078
Patrick Williams6da4f912023-05-10 07:50:53 -050079 const std::map<Type, generatePDR>
80 generateHandlers = {{PLDM_STATE_EFFECTER_PDR,
81 [this](const DBusHandler& dBusIntf,
82 const auto& json, RepoInterface& repo) {
83 pdr_state_effecter::generateStateEffecterPDR<pldm::utils::DBusHandler,
84 Handler>(dBusIntf, json,
85 *this, repo);
86 }},
87 {PLDM_NUMERIC_EFFECTER_PDR,
88 [this](const DBusHandler& dBusIntf,
89 const auto& json, RepoInterface& repo) {
90 pdr_numeric_effecter::generateNumericEffecterPDR<
91 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this, repo);
92 }},
George Liuadbe1722020-05-09 19:20:19 +080093 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf,
94 const auto& json, RepoInterface& repo) {
95 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler,
96 Handler>(dBusIntf, json,
97 *this, repo);
George Liua2870722020-02-11 11:09:30 +080098 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -060099
100 Type pdrType{};
101 for (const auto& dirEntry : fs::directory_iterator(dir))
102 {
103 try
104 {
105 auto json = readJson(dirEntry.path().string());
106 if (!json.empty())
107 {
George Liu1ec85d42020-02-12 16:05:32 +0800108 auto effecterPDRs = json.value("effecterPDRs", empty);
109 for (const auto& effecter : effecterPDRs)
110 {
111 pdrType = effecter.value("pdrType", 0);
George Liu36e81352020-07-01 14:40:30 +0800112 generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +0800113 }
George Liuadbe1722020-05-09 19:20:19 +0800114
115 auto sensorPDRs = json.value("sensorPDRs", empty);
116 for (const auto& sensor : sensorPDRs)
117 {
118 pdrType = sensor.value("pdrType", 0);
119 generateHandlers.at(pdrType)(dBusIntf, sensor, repo);
120 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600121 }
122 }
123 catch (const InternalFailure& e)
124 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600125 error(
126 "PDR config directory does not exist or empty, TYPE= {PDR_TYPE} PATH={DIR_PATH} ERROR={ERR_EXCEP}",
127 "PDR_TYPE", pdrType, "DIR_PATH", dirEntry.path().string(),
128 "ERR_EXCEP", e.what());
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600129 }
130 catch (const Json::exception& e)
131 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600132 error(
133 "Failed parsing PDR JSON file, TYPE={PDR_TYPE} ERROR={ERR_EXCEP}",
134 "PDR_TYPE", pdrType, "ERR_EXCEP", e.what());
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600135 pldm::utils::reportError(
136 "xyz.openbmc_project.bmc.pldm.InternalFailure");
137 }
138 catch (const std::exception& e)
139 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600140 error(
141 "Failed parsing PDR JSON file, TYPE= {PDR_TYPE} ERROR={ERR_EXCEP}",
142 "PDR_TYPE", pdrType, "ERR_EXCEP", e.what());
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600143 pldm::utils::reportError(
144 "xyz.openbmc_project.bmc.pldm.InternalFailure");
145 }
146 }
147}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530148
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600149Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530150{
Pavithra Barithaya99854a72021-09-29 06:58:11 -0500151 if (hostPDRHandler)
152 {
153 if (hostPDRHandler->isHostUp() && oemPlatformHandler != nullptr)
154 {
155 auto rc = oemPlatformHandler->checkBMCState();
156 if (rc != PLDM_SUCCESS)
157 {
158 return ccOnlyResponse(request, PLDM_ERROR_NOT_READY);
159 }
160 }
161 }
162
163 // Build FRU table if not built, since entity association PDR's
164 // are built when the FRU table is constructed.
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530165 if (fruHandler)
166 {
167 fruHandler->buildFRUTable();
168 }
169
George Liud680ae02020-07-17 09:11:14 +0800170 if (!pdrCreated)
171 {
172 generateTerminusLocatorPDR(pdrRepo);
173 generate(*dBusIntf, pdrJsonsDir, pdrRepo);
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500174 if (oemPlatformHandler != nullptr)
175 {
176 oemPlatformHandler->buildOEMPDR(pdrRepo);
177 }
178
George Liud680ae02020-07-17 09:11:14 +0800179 pdrCreated = true;
George Liu5eed8e52020-12-18 11:24:37 +0800180
181 if (dbusToPLDMEventHandler)
182 {
Sampa Misra5fb37d52021-03-06 07:26:00 -0600183 deferredGetPDREvent = std::make_unique<sdeventplus::source::Defer>(
184 event,
185 std::bind(std::mem_fn(&pldm::responder::platform::Handler::
186 _processPostGetPDRActions),
187 this, std::placeholders::_1));
George Liu5eed8e52020-12-18 11:24:37 +0800188 }
George Liud680ae02020-07-17 09:11:14 +0800189 }
190
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530191 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530192
193 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
194 {
George Liufb8611d2019-12-06 10:14:15 +0800195 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530196 }
197
198 uint32_t recordHandle{};
199 uint32_t dataTransferHandle{};
200 uint8_t transferOpFlag{};
201 uint16_t reqSizeBytes{};
202 uint16_t recordChangeNum{};
203
George Liufb8611d2019-12-06 10:14:15 +0800204 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
205 &dataTransferHandle, &transferOpFlag,
206 &reqSizeBytes, &recordChangeNum);
207 if (rc != PLDM_SUCCESS)
208 {
209 return CmdHandler::ccOnlyResponse(request, rc);
210 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530211
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530212 uint16_t respSizeBytes{};
213 uint8_t* recordData = nullptr;
214 try
215 {
George Liue53193f2020-02-24 09:23:26 +0800216 pdr_utils::PdrEntry e;
217 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
218 if (record == NULL)
219 {
220 return CmdHandler::ccOnlyResponse(
221 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
222 }
223
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530224 if (reqSizeBytes)
225 {
George Liue53193f2020-02-24 09:23:26 +0800226 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530227 if (respSizeBytes > reqSizeBytes)
228 {
229 respSizeBytes = reqSizeBytes;
230 }
George Liue53193f2020-02-24 09:23:26 +0800231 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530232 }
233 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
234 respSizeBytes,
235 0);
Manojkiran Eda31a78442021-09-12 15:18:25 +0530236 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500237 rc = encode_get_pdr_resp(
238 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
239 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800240 if (rc != PLDM_SUCCESS)
241 {
242 return ccOnlyResponse(request, rc);
243 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530244 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530245 catch (const std::exception& e)
246 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600247 error("Error accessing PDR, HANDLE={REC_HANDLE} ERROR={ERR_EXCEP}",
248 "REC_HANDLE", recordHandle, "ERR_EXCEP", e.what());
George Liufb8611d2019-12-06 10:14:15 +0800249 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530250 }
251 return response;
252}
253
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600254Response Handler::setStateEffecterStates(const pldm_msg* request,
255 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500256{
257 Response response(
258 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
259 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
260 uint16_t effecterId;
261 uint8_t compEffecterCnt;
262 constexpr auto maxCompositeEffecterCnt = 8;
263 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
264 {0, 0});
265
266 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
267 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
268 sizeof(set_effecter_state_field)))
269 {
George Liufb8611d2019-12-06 10:14:15 +0800270 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500271 }
272
273 int rc = decode_set_state_effecter_states_req(request, payloadLength,
274 &effecterId, &compEffecterCnt,
275 stateField.data());
276
George Liufb8611d2019-12-06 10:14:15 +0800277 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500278 {
George Liufb8611d2019-12-06 10:14:15 +0800279 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500280 }
281
George Liufb8611d2019-12-06 10:14:15 +0800282 stateField.resize(compEffecterCnt);
283 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500284 uint16_t entityType{};
285 uint16_t entityInstance{};
286 uint16_t stateSetId{};
287
288 if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
289 entityInstance, stateSetId) &&
Manojkiran Eda321804e2022-03-03 12:36:54 +0530290 oemPlatformHandler != nullptr &&
291 !effecterDbusObjMaps.contains(effecterId))
Sampa Misraaea5dde2020-08-31 08:33:47 -0500292 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500293 rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
Varsha Kaverappa3fbd39e2020-09-28 01:40:22 -0500294 entityType, entityInstance, stateSetId, compEffecterCnt, stateField,
295 effecterId);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500296 }
297 else
298 {
299 rc = platform_state_effecter::setStateEffecterStatesHandler<
300 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
301 stateField);
302 }
George Liufb8611d2019-12-06 10:14:15 +0800303 if (rc != PLDM_SUCCESS)
304 {
305 return CmdHandler::ccOnlyResponse(request, rc);
306 }
307
308 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
309 responsePtr);
310 if (rc != PLDM_SUCCESS)
311 {
312 return ccOnlyResponse(request, rc);
313 }
314
Sampa Misraa2fa0702019-05-31 01:28:55 -0500315 return response;
316}
317
Tom Joseph56e45c52020-03-16 10:01:45 +0530318Response Handler::platformEventMessage(const pldm_msg* request,
319 size_t payloadLength)
320{
321 uint8_t formatVersion{};
322 uint8_t tid{};
323 uint8_t eventClass{};
324 size_t offset{};
325
326 auto rc = decode_platform_event_message_req(
327 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
328 if (rc != PLDM_SUCCESS)
329 {
330 return CmdHandler::ccOnlyResponse(request, rc);
331 }
332
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500333 if (eventClass == PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT)
Tom Joseph56e45c52020-03-16 10:01:45 +0530334 {
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500335 rc = PLDM_SUCCESS;
Sagar Srinivas79669c92021-04-28 15:43:30 -0500336 if (oemPlatformHandler)
337 {
338 oemPlatformHandler->resetWatchDogTimer();
339 }
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500340 }
341 else
342 {
343 try
Tom Joseph56e45c52020-03-16 10:01:45 +0530344 {
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500345 const auto& handlers = eventHandlers.at(eventClass);
346 for (const auto& handler : handlers)
Tom Joseph56e45c52020-03-16 10:01:45 +0530347 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500348 auto rc = handler(request, payloadLength, formatVersion, tid,
349 offset);
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500350 if (rc != PLDM_SUCCESS)
351 {
352 return CmdHandler::ccOnlyResponse(request, rc);
353 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530354 }
355 }
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500356 catch (const std::out_of_range& e)
357 {
358 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
359 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530360 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530361 Response response(
362 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
363 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
364
365 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
366 PLDM_EVENT_NO_LOGGING, responsePtr);
367 if (rc != PLDM_SUCCESS)
368 {
369 return ccOnlyResponse(request, rc);
370 }
371
372 return response;
373}
374
375int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
Tom Josephc4959c32020-04-20 19:50:16 +0530376 uint8_t /*formatVersion*/, uint8_t tid,
Tom Joseph56e45c52020-03-16 10:01:45 +0530377 size_t eventDataOffset)
378{
379 uint16_t sensorId{};
380 uint8_t eventClass{};
381 size_t eventClassDataOffset{};
Patrick Williams6da4f912023-05-10 07:50:53 -0500382 auto eventData = reinterpret_cast<const uint8_t*>(request->payload) +
383 eventDataOffset;
Tom Joseph56e45c52020-03-16 10:01:45 +0530384 auto eventDataSize = payloadLength - eventDataOffset;
385
386 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
387 &eventClass, &eventClassDataOffset);
388 if (rc != PLDM_SUCCESS)
389 {
390 return rc;
391 }
392
Zahed Hossain75330f32020-03-24 02:15:03 -0500393 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
394 eventDataOffset + eventClassDataOffset;
Patrick Williams6da4f912023-05-10 07:50:53 -0500395 auto eventClassDataSize = payloadLength - eventDataOffset -
396 eventClassDataOffset;
Zahed Hossain75330f32020-03-24 02:15:03 -0500397
Tom Joseph56e45c52020-03-16 10:01:45 +0530398 if (eventClass == PLDM_STATE_SENSOR_STATE)
399 {
400 uint8_t sensorOffset{};
401 uint8_t eventState{};
402 uint8_t previousEventState{};
403
Zahed Hossain75330f32020-03-24 02:15:03 -0500404 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530405 &sensorOffset, &eventState,
406 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500407 if (rc != PLDM_SUCCESS)
408 {
409 return PLDM_ERROR;
410 }
411
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800412 // Emitting state sensor event signal
413 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
414 previousEventState);
415
Tom Josephc4959c32020-04-20 19:50:16 +0530416 // If there are no HOST PDR's, there is no further action
417 if (hostPDRHandler == NULL)
418 {
419 return PLDM_SUCCESS;
420 }
421
422 // Handle PLDM events for which PDR is available
423 SensorEntry sensorEntry{tid, sensorId};
Tom Josephb70a1962020-07-13 12:56:31 +0530424
425 pldm::pdr::EntityInfo entityInfo{};
426 pldm::pdr::CompositeSensorStates compositeSensorStates{};
427
Tom Josephc4959c32020-04-20 19:50:16 +0530428 try
429 {
Tom Josephb70a1962020-07-13 12:56:31 +0530430 std::tie(entityInfo, compositeSensorStates) =
Tom Josephc4959c32020-04-20 19:50:16 +0530431 hostPDRHandler->lookupSensorInfo(sensorEntry);
Tom Josephc4959c32020-04-20 19:50:16 +0530432 }
Tom Josephc4959c32020-04-20 19:50:16 +0530433 catch (const std::out_of_range& e)
434 {
Tom Josephb70a1962020-07-13 12:56:31 +0530435 // If there is no mapping for tid, sensorId combination, try
436 // PLDM_TID_RESERVED, sensorId for terminus that is yet to
437 // implement TL PDR.
438 try
439 {
440 sensorEntry.terminusID = PLDM_TID_RESERVED;
441 std::tie(entityInfo, compositeSensorStates) =
442 hostPDRHandler->lookupSensorInfo(sensorEntry);
443 }
444 // If there is no mapping for events return PLDM_SUCCESS
445 catch (const std::out_of_range& e)
446 {
447 return PLDM_SUCCESS;
448 }
Zahed Hossain75330f32020-03-24 02:15:03 -0500449 }
Tom Josephb70a1962020-07-13 12:56:31 +0530450
451 if (sensorOffset >= compositeSensorStates.size())
452 {
453 return PLDM_ERROR_INVALID_DATA;
454 }
455
456 const auto& possibleStates = compositeSensorStates[sensorOffset];
457 if (possibleStates.find(eventState) == possibleStates.end())
458 {
459 return PLDM_ERROR_INVALID_DATA;
460 }
461
462 const auto& [containerId, entityType, entityInstance] = entityInfo;
463 events::StateSensorEntry stateSensorEntry{containerId, entityType,
464 entityInstance, sensorOffset};
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600465 return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
466 eventState);
Tom Joseph56e45c52020-03-16 10:01:45 +0530467 }
468 else
469 {
470 return PLDM_ERROR_INVALID_DATA;
471 }
472
473 return PLDM_SUCCESS;
474}
475
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500476int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
477 size_t payloadLength,
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530478 uint8_t /*formatVersion*/, uint8_t tid,
479 size_t eventDataOffset)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500480{
481 uint8_t eventDataFormat{};
482 uint8_t numberOfChangeRecords{};
483 size_t dataOffset{};
484
Patrick Williams6da4f912023-05-10 07:50:53 -0500485 auto eventData = reinterpret_cast<const uint8_t*>(request->payload) +
486 eventDataOffset;
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500487 auto eventDataSize = payloadLength - eventDataOffset;
488
489 auto rc = decode_pldm_pdr_repository_chg_event_data(
490 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
491 &dataOffset);
492 if (rc != PLDM_SUCCESS)
493 {
494 return rc;
495 }
496
497 PDRRecordHandles pdrRecordHandles;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500498
499 if (eventDataFormat == FORMAT_IS_PDR_TYPES)
500 {
501 return PLDM_ERROR_INVALID_DATA;
502 }
503
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500504 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
505 {
506 uint8_t eventDataOperation{};
507 uint8_t numberOfChangeEntries{};
508
509 auto changeRecordData = eventData + dataOffset;
510 auto changeRecordDataSize = eventDataSize - dataOffset;
511
512 while (changeRecordDataSize)
513 {
514 rc = decode_pldm_pdr_repository_change_record_data(
515 changeRecordData, changeRecordDataSize, &eventDataOperation,
516 &numberOfChangeEntries, &dataOffset);
517
518 if (rc != PLDM_SUCCESS)
519 {
520 return rc;
521 }
522
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500523 if (eventDataOperation == PLDM_RECORDS_ADDED ||
524 eventDataOperation == PLDM_RECORDS_MODIFIED)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500525 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500526 if (eventDataOperation == PLDM_RECORDS_MODIFIED)
527 {
528 hostPDRHandler->isHostPdrModified = true;
529 }
530
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500531 rc = getPDRRecordHandles(
532 reinterpret_cast<const ChangeEntry*>(changeRecordData +
533 dataOffset),
534 changeRecordDataSize - dataOffset,
535 static_cast<size_t>(numberOfChangeEntries),
536 pdrRecordHandles);
537
538 if (rc != PLDM_SUCCESS)
539 {
540 return rc;
541 }
542 }
543
Patrick Williams6da4f912023-05-10 07:50:53 -0500544 changeRecordData += dataOffset +
545 (numberOfChangeEntries * sizeof(ChangeEntry));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500546 changeRecordDataSize -=
547 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
548 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500549 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500550 if (hostPDRHandler)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500551 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530552 // if we get a Repository change event with the eventDataFormat
553 // as REFRESH_ENTIRE_REPOSITORY, then delete all the PDR's that
554 // have the matched Terminus handle
555 if (eventDataFormat == REFRESH_ENTIRE_REPOSITORY)
556 {
557 // We cannot get the Repo change event from the Terminus
558 // that is not already added to the BMC repository
559
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500560 for (auto it = hostPDRHandler->tlPDRInfo.cbegin();
561 it != hostPDRHandler->tlPDRInfo.cend();)
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530562 {
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500563 if (std::get<0>(it->second) == tid)
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530564 {
565 pldm_pdr_remove_pdrs_by_terminus_handle(pdrRepo.getPdr(),
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500566 it->first);
567 hostPDRHandler->tlPDRInfo.erase(it++);
568 }
569 else
570 {
571 ++it;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530572 }
573 }
574 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500575 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500576 }
577
578 return PLDM_SUCCESS;
579}
580
581int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
582 size_t changeEntryDataSize,
583 size_t numberOfChangeEntries,
584 PDRRecordHandles& pdrRecordHandles)
585{
586 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
587 {
588 return PLDM_ERROR_INVALID_DATA;
589 }
590 for (size_t i = 0; i < numberOfChangeEntries; i++)
591 {
592 pdrRecordHandles.push_back(changeEntryData[i]);
593 }
594 return PLDM_SUCCESS;
595}
596
George Liueccb0c52020-01-14 11:09:56 +0800597Response Handler::setNumericEffecterValue(const pldm_msg* request,
598 size_t payloadLength)
599{
600 Response response(sizeof(pldm_msg_hdr) +
601 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
602 uint16_t effecterId{};
603 uint8_t effecterDataSize{};
604 uint8_t effecterValue[4] = {};
605
606 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
607 sizeof(union_effecter_data_size)) ||
608 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
609 {
610 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
611 }
612
613 int rc = decode_set_numeric_effecter_value_req(
Andrew Jeffery8fbf3cc2023-04-12 13:42:29 +0930614 request, payloadLength, &effecterId, &effecterDataSize, effecterValue);
George Liueccb0c52020-01-14 11:09:56 +0800615
616 if (rc == PLDM_SUCCESS)
617 {
618 const pldm::utils::DBusHandler dBusIntf;
619 rc = platform_numeric_effecter::setNumericEffecterValueHandler<
620 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
621 effecterDataSize, effecterValue,
622 sizeof(effecterValue));
623 }
624
625 return ccOnlyResponse(request, rc);
626}
627
Sampa Misra12afe112020-05-25 11:40:44 -0500628void Handler::generateTerminusLocatorPDR(Repo& repo)
629{
630 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
631
632 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
633
634 pdr->hdr.record_handle = 0;
635 pdr->hdr.version = 1;
636 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
637 pdr->hdr.record_change_num = 0;
638 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
Manojkiran Edacc5f1582021-09-29 17:03:06 +0530639 pdr->terminus_handle = TERMINUS_HANDLE;
Sampa Misra12afe112020-05-25 11:40:44 -0500640 pdr->validity = PLDM_TL_PDR_VALID;
Manojkiran Edacc5f1582021-09-29 17:03:06 +0530641 pdr->tid = TERMINUS_ID;
Sampa Misra12afe112020-05-25 11:40:44 -0500642 pdr->container_id = 0x0;
643 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
644 pdr->terminus_locator_value_size =
645 sizeof(pldm_terminus_locator_type_mctp_eid);
646 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
647 pdr->terminus_locator_value);
648 locatorValue->eid = BmcMctpEid;
649
650 PdrEntry pdrEntry{};
651 pdrEntry.data = pdrBuffer.data();
652 pdrEntry.size = pdrBuffer.size();
653 repo.addRecord(pdrEntry);
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530654 if (hostPDRHandler)
655 {
656 hostPDRHandler->tlPDRInfo.insert_or_assign(
657 pdr->terminus_handle,
658 std::make_tuple(pdr->tid, locatorValue->eid, pdr->validity));
659 }
Sampa Misra12afe112020-05-25 11:40:44 -0500660}
George Liu362c18d2020-05-14 09:46:36 +0800661
662Response Handler::getStateSensorReadings(const pldm_msg* request,
663 size_t payloadLength)
664{
665 uint16_t sensorId{};
666 bitfield8_t sensorRearm{};
667 uint8_t reserved{};
668
Pavithra Barithaya87083f22023-04-17 01:27:49 -0500669 if (payloadLength != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES)
George Liu362c18d2020-05-14 09:46:36 +0800670 {
671 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
672 }
673
674 int rc = decode_get_state_sensor_readings_req(
675 request, payloadLength, &sensorId, &sensorRearm, &reserved);
676
677 if (rc != PLDM_SUCCESS)
678 {
679 return ccOnlyResponse(request, rc);
680 }
681
682 // 0x01 to 0x08
George Liuc1230ca2021-08-03 16:06:50 +0800683 uint8_t sensorRearmCount = std::popcount(sensorRearm.byte);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500684 std::vector<get_sensor_state_field> stateField(sensorRearmCount);
George Liu362c18d2020-05-14 09:46:36 +0800685 uint8_t comSensorCnt{};
686 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500687
688 uint16_t entityType{};
689 uint16_t entityInstance{};
690 uint16_t stateSetId{};
691
692 if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
693 entityType, entityInstance, stateSetId) &&
Manojkiran Eda321804e2022-03-03 12:36:54 +0530694 oemPlatformHandler != nullptr && !sensorDbusObjMaps.contains(sensorId))
Sampa Misraaea5dde2020-08-31 08:33:47 -0500695 {
696 rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
697 entityType, entityInstance, stateSetId, comSensorCnt, stateField);
698 }
699 else
700 {
701 rc = platform_state_sensor::getStateSensorReadingsHandler<
702 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId,
703 sensorRearmCount, comSensorCnt,
704 stateField);
705 }
George Liu362c18d2020-05-14 09:46:36 +0800706
707 if (rc != PLDM_SUCCESS)
708 {
709 return ccOnlyResponse(request, rc);
710 }
711
712 Response response(sizeof(pldm_msg_hdr) +
713 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
714 sizeof(get_sensor_state_field) * comSensorCnt);
715 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
716 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
717 comSensorCnt, stateField.data(),
718 responsePtr);
719 if (rc != PLDM_SUCCESS)
720 {
721 return ccOnlyResponse(request, rc);
722 }
723
724 return response;
725}
726
Pavithra Barithaya99854a72021-09-29 06:58:11 -0500727void Handler::_processPostGetPDRActions(sdeventplus::source::EventBase&
728 /*source */)
Sampa Misra5fb37d52021-03-06 07:26:00 -0600729{
730 deferredGetPDREvent.reset();
731 dbusToPLDMEventHandler->listenSensorEvent(pdrRepo, sensorDbusObjMaps);
732}
733
Sampa Misraaea5dde2020-08-31 08:33:47 -0500734bool isOemStateSensor(Handler& handler, uint16_t sensorId,
735 uint8_t sensorRearmCount, uint8_t& compSensorCnt,
736 uint16_t& entityType, uint16_t& entityInstance,
737 uint16_t& stateSetId)
738{
739 pldm_state_sensor_pdr* pdr = nullptr;
740
741 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
742 pldm_pdr_init(), pldm_pdr_destroy);
743 Repo stateSensorPDRs(stateSensorPdrRepo.get());
744 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
745 if (stateSensorPDRs.empty())
746 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600747 error("Failed to get record by PDR type");
Sampa Misraaea5dde2020-08-31 08:33:47 -0500748 return false;
749 }
750
751 PdrEntry pdrEntry{};
752 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
753 while (pdrRecord)
754 {
755 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
756 assert(pdr != NULL);
757 if (pdr->sensor_id != sensorId)
758 {
759 pdr = nullptr;
760 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
761 continue;
762 }
763 auto tmpEntityType = pdr->entity_type;
764 auto tmpEntityInstance = pdr->entity_instance;
765 auto tmpCompSensorCnt = pdr->composite_sensor_count;
766 auto tmpPossibleStates =
767 reinterpret_cast<state_sensor_possible_states*>(
768 pdr->possible_states);
769 auto tmpStateSetId = tmpPossibleStates->state_set_id;
770
771 if (sensorRearmCount > tmpCompSensorCnt)
772 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600773 error(
774 "The requester sent wrong sensorRearm count for the sensor, SENSOR_ID={SENSOR_ID} SENSOR_REARM_COUNT={SENSOR_REARM_CNT}",
775 "SENSOR_ID", sensorId, "SENSOR_REARM_CNT",
776 (uint16_t)sensorRearmCount);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500777 break;
778 }
779
780 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
781 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
782 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
783 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
784 {
785 entityType = tmpEntityType;
786 entityInstance = tmpEntityInstance;
787 stateSetId = tmpStateSetId;
788 compSensorCnt = tmpCompSensorCnt;
789 return true;
790 }
791 else
792 {
793 return false;
794 }
795 }
796 return false;
797}
798
799bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
800 uint8_t compEffecterCnt, uint16_t& entityType,
801 uint16_t& entityInstance, uint16_t& stateSetId)
802{
803 pldm_state_effecter_pdr* pdr = nullptr;
804
805 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
806 pldm_pdr_init(), pldm_pdr_destroy);
807 Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
808 getRepoByType(handler.getRepo(), stateEffecterPDRs,
809 PLDM_STATE_EFFECTER_PDR);
810 if (stateEffecterPDRs.empty())
811 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600812 error("Failed to get record by PDR type");
Sampa Misraaea5dde2020-08-31 08:33:47 -0500813 return false;
814 }
815
816 PdrEntry pdrEntry{};
817 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
818 while (pdrRecord)
819 {
820 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
821 assert(pdr != NULL);
822 if (pdr->effecter_id != effecterId)
823 {
824 pdr = nullptr;
825 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
826 continue;
827 }
828
829 auto tmpEntityType = pdr->entity_type;
830 auto tmpEntityInstance = pdr->entity_instance;
831 auto tmpPossibleStates =
832 reinterpret_cast<state_effecter_possible_states*>(
833 pdr->possible_states);
834 auto tmpStateSetId = tmpPossibleStates->state_set_id;
835
836 if (compEffecterCnt > pdr->composite_effecter_count)
837 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600838 error(
839 "The requester sent wrong composite effecter count for the effecter, EFFECTER_ID={EFFECTER_ID} COMP_EFF_CNT={COMP_EFF_CNT}",
840 "EFFECTER_ID", effecterId, "COMP_EFF_CNT",
841 (uint16_t)compEffecterCnt);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500842 return false;
843 }
844
845 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
846 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
847 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
848 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
849 {
850 entityType = tmpEntityType;
851 entityInstance = tmpEntityInstance;
852 stateSetId = tmpStateSetId;
853 return true;
854 }
855 else
856 {
857 return false;
858 }
859 }
860 return false;
861}
862
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600863} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530864} // namespace responder
865} // namespace pldm