blob: 38dc9df47c00688f7721accc2b2fe60ce42ef21d [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
79 const std::map<Type, generatePDR> generateHandlers = {
80 {PLDM_STATE_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +080081 [this](const DBusHandler& dBusIntf, const auto& json,
82 RepoInterface& repo) {
83 pdr_state_effecter::generateStateEffecterPDR<
84 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
85 repo);
George Liu456c9a22020-01-13 11:36:22 +080086 }},
87 {PLDM_NUMERIC_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +080088 [this](const DBusHandler& dBusIntf, const auto& json,
89 RepoInterface& repo) {
90 pdr_numeric_effecter::generateNumericEffecterPDR<
91 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
92 repo);
George Liuadbe1722020-05-09 19:20:19 +080093 }},
94 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf,
95 const auto& json, RepoInterface& repo) {
96 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler,
97 Handler>(dBusIntf, json,
98 *this, repo);
George Liua2870722020-02-11 11:09:30 +080099 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600100
101 Type pdrType{};
102 for (const auto& dirEntry : fs::directory_iterator(dir))
103 {
104 try
105 {
106 auto json = readJson(dirEntry.path().string());
107 if (!json.empty())
108 {
George Liu1ec85d42020-02-12 16:05:32 +0800109 auto effecterPDRs = json.value("effecterPDRs", empty);
110 for (const auto& effecter : effecterPDRs)
111 {
112 pdrType = effecter.value("pdrType", 0);
George Liu36e81352020-07-01 14:40:30 +0800113 generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +0800114 }
George Liuadbe1722020-05-09 19:20:19 +0800115
116 auto sensorPDRs = json.value("sensorPDRs", empty);
117 for (const auto& sensor : sensorPDRs)
118 {
119 pdrType = sensor.value("pdrType", 0);
120 generateHandlers.at(pdrType)(dBusIntf, sensor, repo);
121 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600122 }
123 }
124 catch (const InternalFailure& e)
125 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600126 error(
127 "PDR config directory does not exist or empty, TYPE= {PDR_TYPE} PATH={DIR_PATH} ERROR={ERR_EXCEP}",
128 "PDR_TYPE", pdrType, "DIR_PATH", dirEntry.path().string(),
129 "ERR_EXCEP", e.what());
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600130 }
131 catch (const Json::exception& e)
132 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600133 error(
134 "Failed parsing PDR JSON file, TYPE={PDR_TYPE} ERROR={ERR_EXCEP}",
135 "PDR_TYPE", pdrType, "ERR_EXCEP", e.what());
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600136 pldm::utils::reportError(
137 "xyz.openbmc_project.bmc.pldm.InternalFailure");
138 }
139 catch (const std::exception& e)
140 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600141 error(
142 "Failed parsing PDR JSON file, TYPE= {PDR_TYPE} ERROR={ERR_EXCEP}",
143 "PDR_TYPE", pdrType, "ERR_EXCEP", e.what());
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600144 pldm::utils::reportError(
145 "xyz.openbmc_project.bmc.pldm.InternalFailure");
146 }
147 }
148}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530149
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600150Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530151{
Pavithra Barithaya99854a72021-09-29 06:58:11 -0500152 if (hostPDRHandler)
153 {
154 if (hostPDRHandler->isHostUp() && oemPlatformHandler != nullptr)
155 {
156 auto rc = oemPlatformHandler->checkBMCState();
157 if (rc != PLDM_SUCCESS)
158 {
159 return ccOnlyResponse(request, PLDM_ERROR_NOT_READY);
160 }
161 }
162 }
163
164 // Build FRU table if not built, since entity association PDR's
165 // are built when the FRU table is constructed.
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530166 if (fruHandler)
167 {
168 fruHandler->buildFRUTable();
169 }
170
George Liud680ae02020-07-17 09:11:14 +0800171 if (!pdrCreated)
172 {
173 generateTerminusLocatorPDR(pdrRepo);
174 generate(*dBusIntf, pdrJsonsDir, pdrRepo);
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500175 if (oemPlatformHandler != nullptr)
176 {
177 oemPlatformHandler->buildOEMPDR(pdrRepo);
178 }
179
George Liud680ae02020-07-17 09:11:14 +0800180 pdrCreated = true;
George Liu5eed8e52020-12-18 11:24:37 +0800181
182 if (dbusToPLDMEventHandler)
183 {
Sampa Misra5fb37d52021-03-06 07:26:00 -0600184 deferredGetPDREvent = std::make_unique<sdeventplus::source::Defer>(
185 event,
186 std::bind(std::mem_fn(&pldm::responder::platform::Handler::
187 _processPostGetPDRActions),
188 this, std::placeholders::_1));
George Liu5eed8e52020-12-18 11:24:37 +0800189 }
George Liud680ae02020-07-17 09:11:14 +0800190 }
191
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530192 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530193
194 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
195 {
George Liufb8611d2019-12-06 10:14:15 +0800196 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530197 }
198
199 uint32_t recordHandle{};
200 uint32_t dataTransferHandle{};
201 uint8_t transferOpFlag{};
202 uint16_t reqSizeBytes{};
203 uint16_t recordChangeNum{};
204
George Liufb8611d2019-12-06 10:14:15 +0800205 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
206 &dataTransferHandle, &transferOpFlag,
207 &reqSizeBytes, &recordChangeNum);
208 if (rc != PLDM_SUCCESS)
209 {
210 return CmdHandler::ccOnlyResponse(request, rc);
211 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530212
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530213 uint16_t respSizeBytes{};
214 uint8_t* recordData = nullptr;
215 try
216 {
George Liue53193f2020-02-24 09:23:26 +0800217 pdr_utils::PdrEntry e;
218 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
219 if (record == NULL)
220 {
221 return CmdHandler::ccOnlyResponse(
222 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
223 }
224
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530225 if (reqSizeBytes)
226 {
George Liue53193f2020-02-24 09:23:26 +0800227 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530228 if (respSizeBytes > reqSizeBytes)
229 {
230 respSizeBytes = reqSizeBytes;
231 }
George Liue53193f2020-02-24 09:23:26 +0800232 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530233 }
234 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
235 respSizeBytes,
236 0);
Manojkiran Eda31a78442021-09-12 15:18:25 +0530237 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500238 rc = encode_get_pdr_resp(
239 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
240 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800241 if (rc != PLDM_SUCCESS)
242 {
243 return ccOnlyResponse(request, rc);
244 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530245 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530246 catch (const std::exception& e)
247 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600248 error("Error accessing PDR, HANDLE={REC_HANDLE} ERROR={ERR_EXCEP}",
249 "REC_HANDLE", recordHandle, "ERR_EXCEP", e.what());
George Liufb8611d2019-12-06 10:14:15 +0800250 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530251 }
252 return response;
253}
254
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600255Response Handler::setStateEffecterStates(const pldm_msg* request,
256 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500257{
258 Response response(
259 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
260 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
261 uint16_t effecterId;
262 uint8_t compEffecterCnt;
263 constexpr auto maxCompositeEffecterCnt = 8;
264 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
265 {0, 0});
266
267 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
268 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
269 sizeof(set_effecter_state_field)))
270 {
George Liufb8611d2019-12-06 10:14:15 +0800271 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500272 }
273
274 int rc = decode_set_state_effecter_states_req(request, payloadLength,
275 &effecterId, &compEffecterCnt,
276 stateField.data());
277
George Liufb8611d2019-12-06 10:14:15 +0800278 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500279 {
George Liufb8611d2019-12-06 10:14:15 +0800280 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500281 }
282
George Liufb8611d2019-12-06 10:14:15 +0800283 stateField.resize(compEffecterCnt);
284 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500285 uint16_t entityType{};
286 uint16_t entityInstance{};
287 uint16_t stateSetId{};
288
289 if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
290 entityInstance, stateSetId) &&
Manojkiran Eda321804e2022-03-03 12:36:54 +0530291 oemPlatformHandler != nullptr &&
292 !effecterDbusObjMaps.contains(effecterId))
Sampa Misraaea5dde2020-08-31 08:33:47 -0500293 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500294 rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
Varsha Kaverappa3fbd39e2020-09-28 01:40:22 -0500295 entityType, entityInstance, stateSetId, compEffecterCnt, stateField,
296 effecterId);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500297 }
298 else
299 {
300 rc = platform_state_effecter::setStateEffecterStatesHandler<
301 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
302 stateField);
303 }
George Liufb8611d2019-12-06 10:14:15 +0800304 if (rc != PLDM_SUCCESS)
305 {
306 return CmdHandler::ccOnlyResponse(request, rc);
307 }
308
309 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
310 responsePtr);
311 if (rc != PLDM_SUCCESS)
312 {
313 return ccOnlyResponse(request, rc);
314 }
315
Sampa Misraa2fa0702019-05-31 01:28:55 -0500316 return response;
317}
318
Tom Joseph56e45c52020-03-16 10:01:45 +0530319Response Handler::platformEventMessage(const pldm_msg* request,
320 size_t payloadLength)
321{
322 uint8_t formatVersion{};
323 uint8_t tid{};
324 uint8_t eventClass{};
325 size_t offset{};
326
327 auto rc = decode_platform_event_message_req(
328 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
329 if (rc != PLDM_SUCCESS)
330 {
331 return CmdHandler::ccOnlyResponse(request, rc);
332 }
333
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500334 if (eventClass == PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT)
Tom Joseph56e45c52020-03-16 10:01:45 +0530335 {
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500336 rc = PLDM_SUCCESS;
Sagar Srinivas79669c92021-04-28 15:43:30 -0500337 if (oemPlatformHandler)
338 {
339 oemPlatformHandler->resetWatchDogTimer();
340 }
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500341 }
342 else
343 {
344 try
Tom Joseph56e45c52020-03-16 10:01:45 +0530345 {
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500346 const auto& handlers = eventHandlers.at(eventClass);
347 for (const auto& handler : handlers)
Tom Joseph56e45c52020-03-16 10:01:45 +0530348 {
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500349 auto rc =
350 handler(request, payloadLength, formatVersion, tid, offset);
351 if (rc != PLDM_SUCCESS)
352 {
353 return CmdHandler::ccOnlyResponse(request, rc);
354 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530355 }
356 }
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500357 catch (const std::out_of_range& e)
358 {
359 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
360 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530361 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530362 Response response(
363 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
364 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
365
366 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
367 PLDM_EVENT_NO_LOGGING, responsePtr);
368 if (rc != PLDM_SUCCESS)
369 {
370 return ccOnlyResponse(request, rc);
371 }
372
373 return response;
374}
375
376int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
Tom Josephc4959c32020-04-20 19:50:16 +0530377 uint8_t /*formatVersion*/, uint8_t tid,
Tom Joseph56e45c52020-03-16 10:01:45 +0530378 size_t eventDataOffset)
379{
380 uint16_t sensorId{};
381 uint8_t eventClass{};
382 size_t eventClassDataOffset{};
383 auto eventData =
384 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
385 auto eventDataSize = payloadLength - eventDataOffset;
386
387 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
388 &eventClass, &eventClassDataOffset);
389 if (rc != PLDM_SUCCESS)
390 {
391 return rc;
392 }
393
Zahed Hossain75330f32020-03-24 02:15:03 -0500394 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
395 eventDataOffset + eventClassDataOffset;
396 auto eventClassDataSize =
397 payloadLength - eventDataOffset - eventClassDataOffset;
398
Tom Joseph56e45c52020-03-16 10:01:45 +0530399 if (eventClass == PLDM_STATE_SENSOR_STATE)
400 {
401 uint8_t sensorOffset{};
402 uint8_t eventState{};
403 uint8_t previousEventState{};
404
Zahed Hossain75330f32020-03-24 02:15:03 -0500405 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530406 &sensorOffset, &eventState,
407 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500408 if (rc != PLDM_SUCCESS)
409 {
410 return PLDM_ERROR;
411 }
412
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800413 // Emitting state sensor event signal
414 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
415 previousEventState);
416
Tom Josephc4959c32020-04-20 19:50:16 +0530417 // If there are no HOST PDR's, there is no further action
418 if (hostPDRHandler == NULL)
419 {
420 return PLDM_SUCCESS;
421 }
422
423 // Handle PLDM events for which PDR is available
424 SensorEntry sensorEntry{tid, sensorId};
Tom Josephb70a1962020-07-13 12:56:31 +0530425
426 pldm::pdr::EntityInfo entityInfo{};
427 pldm::pdr::CompositeSensorStates compositeSensorStates{};
428
Tom Josephc4959c32020-04-20 19:50:16 +0530429 try
430 {
Tom Josephb70a1962020-07-13 12:56:31 +0530431 std::tie(entityInfo, compositeSensorStates) =
Tom Josephc4959c32020-04-20 19:50:16 +0530432 hostPDRHandler->lookupSensorInfo(sensorEntry);
Tom Josephc4959c32020-04-20 19:50:16 +0530433 }
Tom Josephc4959c32020-04-20 19:50:16 +0530434 catch (const std::out_of_range& e)
435 {
Tom Josephb70a1962020-07-13 12:56:31 +0530436 // If there is no mapping for tid, sensorId combination, try
437 // PLDM_TID_RESERVED, sensorId for terminus that is yet to
438 // implement TL PDR.
439 try
440 {
441 sensorEntry.terminusID = PLDM_TID_RESERVED;
442 std::tie(entityInfo, compositeSensorStates) =
443 hostPDRHandler->lookupSensorInfo(sensorEntry);
444 }
445 // If there is no mapping for events return PLDM_SUCCESS
446 catch (const std::out_of_range& e)
447 {
448 return PLDM_SUCCESS;
449 }
Zahed Hossain75330f32020-03-24 02:15:03 -0500450 }
Tom Josephb70a1962020-07-13 12:56:31 +0530451
452 if (sensorOffset >= compositeSensorStates.size())
453 {
454 return PLDM_ERROR_INVALID_DATA;
455 }
456
457 const auto& possibleStates = compositeSensorStates[sensorOffset];
458 if (possibleStates.find(eventState) == possibleStates.end())
459 {
460 return PLDM_ERROR_INVALID_DATA;
461 }
462
463 const auto& [containerId, entityType, entityInstance] = entityInfo;
464 events::StateSensorEntry stateSensorEntry{containerId, entityType,
465 entityInstance, sensorOffset};
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600466 return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
467 eventState);
Tom Joseph56e45c52020-03-16 10:01:45 +0530468 }
469 else
470 {
471 return PLDM_ERROR_INVALID_DATA;
472 }
473
474 return PLDM_SUCCESS;
475}
476
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500477int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
478 size_t payloadLength,
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530479 uint8_t /*formatVersion*/, uint8_t tid,
480 size_t eventDataOffset)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500481{
482 uint8_t eventDataFormat{};
483 uint8_t numberOfChangeRecords{};
484 size_t dataOffset{};
485
486 auto eventData =
487 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
488 auto eventDataSize = payloadLength - eventDataOffset;
489
490 auto rc = decode_pldm_pdr_repository_chg_event_data(
491 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
492 &dataOffset);
493 if (rc != PLDM_SUCCESS)
494 {
495 return rc;
496 }
497
498 PDRRecordHandles pdrRecordHandles;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500499
500 if (eventDataFormat == FORMAT_IS_PDR_TYPES)
501 {
502 return PLDM_ERROR_INVALID_DATA;
503 }
504
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500505 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
506 {
507 uint8_t eventDataOperation{};
508 uint8_t numberOfChangeEntries{};
509
510 auto changeRecordData = eventData + dataOffset;
511 auto changeRecordDataSize = eventDataSize - dataOffset;
512
513 while (changeRecordDataSize)
514 {
515 rc = decode_pldm_pdr_repository_change_record_data(
516 changeRecordData, changeRecordDataSize, &eventDataOperation,
517 &numberOfChangeEntries, &dataOffset);
518
519 if (rc != PLDM_SUCCESS)
520 {
521 return rc;
522 }
523
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500524 if (eventDataOperation == PLDM_RECORDS_ADDED ||
525 eventDataOperation == PLDM_RECORDS_MODIFIED)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500526 {
Pavithra Barithayaae5c97e2022-08-29 02:57:59 -0500527 if (eventDataOperation == PLDM_RECORDS_MODIFIED)
528 {
529 hostPDRHandler->isHostPdrModified = true;
530 }
531
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500532 rc = getPDRRecordHandles(
533 reinterpret_cast<const ChangeEntry*>(changeRecordData +
534 dataOffset),
535 changeRecordDataSize - dataOffset,
536 static_cast<size_t>(numberOfChangeEntries),
537 pdrRecordHandles);
538
539 if (rc != PLDM_SUCCESS)
540 {
541 return rc;
542 }
543 }
544
545 changeRecordData +=
546 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
547 changeRecordDataSize -=
548 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
549 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500550 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500551 if (hostPDRHandler)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500552 {
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530553 // if we get a Repository change event with the eventDataFormat
554 // as REFRESH_ENTIRE_REPOSITORY, then delete all the PDR's that
555 // have the matched Terminus handle
556 if (eventDataFormat == REFRESH_ENTIRE_REPOSITORY)
557 {
558 // We cannot get the Repo change event from the Terminus
559 // that is not already added to the BMC repository
560
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500561 for (auto it = hostPDRHandler->tlPDRInfo.cbegin();
562 it != hostPDRHandler->tlPDRInfo.cend();)
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530563 {
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500564 if (std::get<0>(it->second) == tid)
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530565 {
566 pldm_pdr_remove_pdrs_by_terminus_handle(pdrRepo.getPdr(),
Pavithra Barithaya52aad392022-08-02 04:18:52 -0500567 it->first);
568 hostPDRHandler->tlPDRInfo.erase(it++);
569 }
570 else
571 {
572 ++it;
Manojkiran Eda3ca40452021-10-04 22:51:37 +0530573 }
574 }
575 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500576 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500577 }
578
579 return PLDM_SUCCESS;
580}
581
582int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
583 size_t changeEntryDataSize,
584 size_t numberOfChangeEntries,
585 PDRRecordHandles& pdrRecordHandles)
586{
587 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
588 {
589 return PLDM_ERROR_INVALID_DATA;
590 }
591 for (size_t i = 0; i < numberOfChangeEntries; i++)
592 {
593 pdrRecordHandles.push_back(changeEntryData[i]);
594 }
595 return PLDM_SUCCESS;
596}
597
George Liueccb0c52020-01-14 11:09:56 +0800598Response Handler::setNumericEffecterValue(const pldm_msg* request,
599 size_t payloadLength)
600{
601 Response response(sizeof(pldm_msg_hdr) +
602 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
603 uint16_t effecterId{};
604 uint8_t effecterDataSize{};
605 uint8_t effecterValue[4] = {};
606
607 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
608 sizeof(union_effecter_data_size)) ||
609 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
610 {
611 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
612 }
613
614 int rc = decode_set_numeric_effecter_value_req(
Andrew Jeffery8fbf3cc2023-04-12 13:42:29 +0930615 request, payloadLength, &effecterId, &effecterDataSize, effecterValue);
George Liueccb0c52020-01-14 11:09:56 +0800616
617 if (rc == PLDM_SUCCESS)
618 {
619 const pldm::utils::DBusHandler dBusIntf;
620 rc = platform_numeric_effecter::setNumericEffecterValueHandler<
621 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
622 effecterDataSize, effecterValue,
623 sizeof(effecterValue));
624 }
625
626 return ccOnlyResponse(request, rc);
627}
628
Sampa Misra12afe112020-05-25 11:40:44 -0500629void Handler::generateTerminusLocatorPDR(Repo& repo)
630{
631 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
632
633 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
634
635 pdr->hdr.record_handle = 0;
636 pdr->hdr.version = 1;
637 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
638 pdr->hdr.record_change_num = 0;
639 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
Manojkiran Edacc5f1582021-09-29 17:03:06 +0530640 pdr->terminus_handle = TERMINUS_HANDLE;
Sampa Misra12afe112020-05-25 11:40:44 -0500641 pdr->validity = PLDM_TL_PDR_VALID;
Manojkiran Edacc5f1582021-09-29 17:03:06 +0530642 pdr->tid = TERMINUS_ID;
Sampa Misra12afe112020-05-25 11:40:44 -0500643 pdr->container_id = 0x0;
644 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
645 pdr->terminus_locator_value_size =
646 sizeof(pldm_terminus_locator_type_mctp_eid);
647 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
648 pdr->terminus_locator_value);
649 locatorValue->eid = BmcMctpEid;
650
651 PdrEntry pdrEntry{};
652 pdrEntry.data = pdrBuffer.data();
653 pdrEntry.size = pdrBuffer.size();
654 repo.addRecord(pdrEntry);
Manojkiran Eda60e1fe92021-10-08 15:58:16 +0530655 if (hostPDRHandler)
656 {
657 hostPDRHandler->tlPDRInfo.insert_or_assign(
658 pdr->terminus_handle,
659 std::make_tuple(pdr->tid, locatorValue->eid, pdr->validity));
660 }
Sampa Misra12afe112020-05-25 11:40:44 -0500661}
George Liu362c18d2020-05-14 09:46:36 +0800662
663Response Handler::getStateSensorReadings(const pldm_msg* request,
664 size_t payloadLength)
665{
666 uint16_t sensorId{};
667 bitfield8_t sensorRearm{};
668 uint8_t reserved{};
669
Pavithra Barithaya87083f22023-04-17 01:27:49 -0500670 if (payloadLength != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES)
George Liu362c18d2020-05-14 09:46:36 +0800671 {
672 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
673 }
674
675 int rc = decode_get_state_sensor_readings_req(
676 request, payloadLength, &sensorId, &sensorRearm, &reserved);
677
678 if (rc != PLDM_SUCCESS)
679 {
680 return ccOnlyResponse(request, rc);
681 }
682
683 // 0x01 to 0x08
George Liuc1230ca2021-08-03 16:06:50 +0800684 uint8_t sensorRearmCount = std::popcount(sensorRearm.byte);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500685 std::vector<get_sensor_state_field> stateField(sensorRearmCount);
George Liu362c18d2020-05-14 09:46:36 +0800686 uint8_t comSensorCnt{};
687 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500688
689 uint16_t entityType{};
690 uint16_t entityInstance{};
691 uint16_t stateSetId{};
692
693 if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
694 entityType, entityInstance, stateSetId) &&
Manojkiran Eda321804e2022-03-03 12:36:54 +0530695 oemPlatformHandler != nullptr && !sensorDbusObjMaps.contains(sensorId))
Sampa Misraaea5dde2020-08-31 08:33:47 -0500696 {
697 rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
698 entityType, entityInstance, stateSetId, comSensorCnt, stateField);
699 }
700 else
701 {
702 rc = platform_state_sensor::getStateSensorReadingsHandler<
703 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId,
704 sensorRearmCount, comSensorCnt,
705 stateField);
706 }
George Liu362c18d2020-05-14 09:46:36 +0800707
708 if (rc != PLDM_SUCCESS)
709 {
710 return ccOnlyResponse(request, rc);
711 }
712
713 Response response(sizeof(pldm_msg_hdr) +
714 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
715 sizeof(get_sensor_state_field) * comSensorCnt);
716 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
717 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
718 comSensorCnt, stateField.data(),
719 responsePtr);
720 if (rc != PLDM_SUCCESS)
721 {
722 return ccOnlyResponse(request, rc);
723 }
724
725 return response;
726}
727
Pavithra Barithaya99854a72021-09-29 06:58:11 -0500728void Handler::_processPostGetPDRActions(sdeventplus::source::EventBase&
729 /*source */)
Sampa Misra5fb37d52021-03-06 07:26:00 -0600730{
731 deferredGetPDREvent.reset();
732 dbusToPLDMEventHandler->listenSensorEvent(pdrRepo, sensorDbusObjMaps);
733}
734
Sampa Misraaea5dde2020-08-31 08:33:47 -0500735bool isOemStateSensor(Handler& handler, uint16_t sensorId,
736 uint8_t sensorRearmCount, uint8_t& compSensorCnt,
737 uint16_t& entityType, uint16_t& entityInstance,
738 uint16_t& stateSetId)
739{
740 pldm_state_sensor_pdr* pdr = nullptr;
741
742 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
743 pldm_pdr_init(), pldm_pdr_destroy);
744 Repo stateSensorPDRs(stateSensorPdrRepo.get());
745 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
746 if (stateSensorPDRs.empty())
747 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600748 error("Failed to get record by PDR type");
Sampa Misraaea5dde2020-08-31 08:33:47 -0500749 return false;
750 }
751
752 PdrEntry pdrEntry{};
753 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
754 while (pdrRecord)
755 {
756 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
757 assert(pdr != NULL);
758 if (pdr->sensor_id != sensorId)
759 {
760 pdr = nullptr;
761 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
762 continue;
763 }
764 auto tmpEntityType = pdr->entity_type;
765 auto tmpEntityInstance = pdr->entity_instance;
766 auto tmpCompSensorCnt = pdr->composite_sensor_count;
767 auto tmpPossibleStates =
768 reinterpret_cast<state_sensor_possible_states*>(
769 pdr->possible_states);
770 auto tmpStateSetId = tmpPossibleStates->state_set_id;
771
772 if (sensorRearmCount > tmpCompSensorCnt)
773 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600774 error(
775 "The requester sent wrong sensorRearm count for the sensor, SENSOR_ID={SENSOR_ID} SENSOR_REARM_COUNT={SENSOR_REARM_CNT}",
776 "SENSOR_ID", sensorId, "SENSOR_REARM_CNT",
777 (uint16_t)sensorRearmCount);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500778 break;
779 }
780
781 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
782 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
783 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
784 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
785 {
786 entityType = tmpEntityType;
787 entityInstance = tmpEntityInstance;
788 stateSetId = tmpStateSetId;
789 compSensorCnt = tmpCompSensorCnt;
790 return true;
791 }
792 else
793 {
794 return false;
795 }
796 }
797 return false;
798}
799
800bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
801 uint8_t compEffecterCnt, uint16_t& entityType,
802 uint16_t& entityInstance, uint16_t& stateSetId)
803{
804 pldm_state_effecter_pdr* pdr = nullptr;
805
806 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
807 pldm_pdr_init(), pldm_pdr_destroy);
808 Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
809 getRepoByType(handler.getRepo(), stateEffecterPDRs,
810 PLDM_STATE_EFFECTER_PDR);
811 if (stateEffecterPDRs.empty())
812 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600813 error("Failed to get record by PDR type");
Sampa Misraaea5dde2020-08-31 08:33:47 -0500814 return false;
815 }
816
817 PdrEntry pdrEntry{};
818 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
819 while (pdrRecord)
820 {
821 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
822 assert(pdr != NULL);
823 if (pdr->effecter_id != effecterId)
824 {
825 pdr = nullptr;
826 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
827 continue;
828 }
829
830 auto tmpEntityType = pdr->entity_type;
831 auto tmpEntityInstance = pdr->entity_instance;
832 auto tmpPossibleStates =
833 reinterpret_cast<state_effecter_possible_states*>(
834 pdr->possible_states);
835 auto tmpStateSetId = tmpPossibleStates->state_set_id;
836
837 if (compEffecterCnt > pdr->composite_effecter_count)
838 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600839 error(
840 "The requester sent wrong composite effecter count for the effecter, EFFECTER_ID={EFFECTER_ID} COMP_EFF_CNT={COMP_EFF_CNT}",
841 "EFFECTER_ID", effecterId, "COMP_EFF_CNT",
842 (uint16_t)compEffecterCnt);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500843 return false;
844 }
845
846 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
847 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
848 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
849 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
850 {
851 entityType = tmpEntityType;
852 entityInstance = tmpEntityInstance;
853 stateSetId = tmpStateSetId;
854 return true;
855 }
856 else
857 {
858 return false;
859 }
860 }
861 return false;
862}
863
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600864} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530865} // namespace responder
866} // namespace pldm