blob: 779a0cdee65c721c01c5f24d4475273429e49f3f [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301
2#include "platform.hpp"
3
Sampa Misraaea5dde2020-08-31 08:33:47 -05004#include "libpldm/entity.h"
5#include "libpldm/state_set.h"
6
Tom Josephb70a1962020-07-13 12:56:31 +05307#include "common/types.hpp"
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05008#include "common/utils.hpp"
Tom Josephc4959c32020-04-20 19:50:16 +05309#include "event_parser.hpp"
Sampa Misra12afe112020-05-25 11:40:44 -050010#include "pdr.hpp"
George Liu456c9a22020-01-13 11:36:22 +080011#include "pdr_numeric_effecter.hpp"
George Liua2870722020-02-11 11:09:30 +080012#include "pdr_state_effecter.hpp"
George Liuadbe1722020-05-09 19:20:19 +080013#include "pdr_state_sensor.hpp"
George Liu362c18d2020-05-14 09:46:36 +080014#include "pdr_utils.hpp"
George Liueccb0c52020-01-14 11:09:56 +080015#include "platform_numeric_effecter.hpp"
George Liu0d7aca82020-03-30 15:01:36 +080016#include "platform_state_effecter.hpp"
George Liu362c18d2020-05-14 09:46:36 +080017#include "platform_state_sensor.hpp"
George Liu83409572019-12-24 18:42:54 +080018
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053019namespace pldm
20{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053021namespace responder
22{
Sampa Misraa2fa0702019-05-31 01:28:55 -050023namespace platform
24{
25
Deepak Kodihallic682fe22020-03-04 00:42:54 -060026using InternalFailure =
27 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
28
George Liu1ec85d42020-02-12 16:05:32 +080029static const Json empty{};
30
George Liua2870722020-02-11 11:09:30 +080031void Handler::addDbusObjMaps(
George Liuadbe1722020-05-09 19:20:19 +080032 uint16_t id,
33 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
34 TypeId typeId)
George Liu1ec85d42020-02-12 16:05:32 +080035{
George Liuadbe1722020-05-09 19:20:19 +080036 if (typeId == TypeId::PLDM_SENSOR_ID)
37 {
38 sensorDbusObjMaps.emplace(id, dbusObj);
39 }
40 else
41 {
42 effecterDbusObjMaps.emplace(id, dbusObj);
43 }
George Liu1ec85d42020-02-12 16:05:32 +080044}
45
George Liua2870722020-02-11 11:09:30 +080046const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liuadbe1722020-05-09 19:20:19 +080047 Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
George Liu1ec85d42020-02-12 16:05:32 +080048{
George Liuadbe1722020-05-09 19:20:19 +080049 if (typeId == TypeId::PLDM_SENSOR_ID)
50 {
51 return sensorDbusObjMaps.at(id);
52 }
53 else
54 {
55 return effecterDbusObjMaps.at(id);
56 }
George Liu1ec85d42020-02-12 16:05:32 +080057}
58
George Liu36e81352020-07-01 14:40:30 +080059void Handler::generate(const pldm::utils::DBusHandler& dBusIntf,
60 const std::string& dir, Repo& repo)
Deepak Kodihallic682fe22020-03-04 00:42:54 -060061{
Deepak Kodihallic6e49c42020-07-01 03:39:27 -050062 if (!fs::exists(dir))
63 {
64 return;
65 }
66
Deepak Kodihallic682fe22020-03-04 00:42:54 -060067 // A map of PDR type to a lambda that handles creation of that PDR type.
68 // The lambda essentially would parse the platform specific PDR JSONs to
69 // generate the PDR structures. This function iterates through the map to
70 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080071
72 const std::map<Type, generatePDR> generateHandlers = {
73 {PLDM_STATE_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +080074 [this](const DBusHandler& dBusIntf, const auto& json,
75 RepoInterface& repo) {
76 pdr_state_effecter::generateStateEffecterPDR<
77 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
78 repo);
George Liu456c9a22020-01-13 11:36:22 +080079 }},
80 {PLDM_NUMERIC_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +080081 [this](const DBusHandler& dBusIntf, const auto& json,
82 RepoInterface& repo) {
83 pdr_numeric_effecter::generateNumericEffecterPDR<
84 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
85 repo);
George Liuadbe1722020-05-09 19:20:19 +080086 }},
87 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf,
88 const auto& json, RepoInterface& repo) {
89 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler,
90 Handler>(dBusIntf, json,
91 *this, repo);
George Liua2870722020-02-11 11:09:30 +080092 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -060093
94 Type pdrType{};
95 for (const auto& dirEntry : fs::directory_iterator(dir))
96 {
97 try
98 {
99 auto json = readJson(dirEntry.path().string());
100 if (!json.empty())
101 {
George Liu1ec85d42020-02-12 16:05:32 +0800102 auto effecterPDRs = json.value("effecterPDRs", empty);
103 for (const auto& effecter : effecterPDRs)
104 {
105 pdrType = effecter.value("pdrType", 0);
George Liu36e81352020-07-01 14:40:30 +0800106 generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +0800107 }
George Liuadbe1722020-05-09 19:20:19 +0800108
109 auto sensorPDRs = json.value("sensorPDRs", empty);
110 for (const auto& sensor : sensorPDRs)
111 {
112 pdrType = sensor.value("pdrType", 0);
113 generateHandlers.at(pdrType)(dBusIntf, sensor, repo);
114 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600115 }
116 }
117 catch (const InternalFailure& e)
118 {
119 std::cerr << "PDR config directory does not exist or empty, TYPE= "
120 << pdrType << "PATH= " << dirEntry
121 << " ERROR=" << e.what() << "\n";
122 }
123 catch (const Json::exception& e)
124 {
125 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
126 << " ERROR=" << e.what() << "\n";
127 pldm::utils::reportError(
128 "xyz.openbmc_project.bmc.pldm.InternalFailure");
129 }
130 catch (const std::exception& e)
131 {
132 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
133 << " ERROR=" << e.what() << "\n";
134 pldm::utils::reportError(
135 "xyz.openbmc_project.bmc.pldm.InternalFailure");
136 }
137 }
138}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530139
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600140Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530141{
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530142 // Build FRU table if not built, since entity association PDR's are built
143 // when the FRU table is constructed.
144 if (fruHandler)
145 {
146 fruHandler->buildFRUTable();
147 }
148
George Liud680ae02020-07-17 09:11:14 +0800149 if (!pdrCreated)
150 {
151 generateTerminusLocatorPDR(pdrRepo);
152 generate(*dBusIntf, pdrJsonsDir, pdrRepo);
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500153 if (oemPlatformHandler != nullptr)
154 {
155 oemPlatformHandler->buildOEMPDR(pdrRepo);
156 }
157
George Liud680ae02020-07-17 09:11:14 +0800158 pdrCreated = true;
George Liu5eed8e52020-12-18 11:24:37 +0800159
160 if (dbusToPLDMEventHandler)
161 {
Sampa Misra5fb37d52021-03-06 07:26:00 -0600162 deferredGetPDREvent = std::make_unique<sdeventplus::source::Defer>(
163 event,
164 std::bind(std::mem_fn(&pldm::responder::platform::Handler::
165 _processPostGetPDRActions),
166 this, std::placeholders::_1));
George Liu5eed8e52020-12-18 11:24:37 +0800167 }
George Liud680ae02020-07-17 09:11:14 +0800168 }
169
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530170 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
171 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
172
173 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
174 {
George Liufb8611d2019-12-06 10:14:15 +0800175 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530176 }
177
178 uint32_t recordHandle{};
179 uint32_t dataTransferHandle{};
180 uint8_t transferOpFlag{};
181 uint16_t reqSizeBytes{};
182 uint16_t recordChangeNum{};
183
George Liufb8611d2019-12-06 10:14:15 +0800184 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
185 &dataTransferHandle, &transferOpFlag,
186 &reqSizeBytes, &recordChangeNum);
187 if (rc != PLDM_SUCCESS)
188 {
189 return CmdHandler::ccOnlyResponse(request, rc);
190 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530191
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530192 uint16_t respSizeBytes{};
193 uint8_t* recordData = nullptr;
194 try
195 {
George Liue53193f2020-02-24 09:23:26 +0800196 pdr_utils::PdrEntry e;
197 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
198 if (record == NULL)
199 {
200 return CmdHandler::ccOnlyResponse(
201 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
202 }
203
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530204 if (reqSizeBytes)
205 {
George Liue53193f2020-02-24 09:23:26 +0800206 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530207 if (respSizeBytes > reqSizeBytes)
208 {
209 respSizeBytes = reqSizeBytes;
210 }
George Liue53193f2020-02-24 09:23:26 +0800211 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530212 }
213 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
214 respSizeBytes,
215 0);
216 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500217 rc = encode_get_pdr_resp(
218 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
219 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800220 if (rc != PLDM_SUCCESS)
221 {
222 return ccOnlyResponse(request, rc);
223 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530224 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530225 catch (const std::exception& e)
226 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600227 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
228 << " ERROR=" << e.what() << "\n";
George Liufb8611d2019-12-06 10:14:15 +0800229 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530230 }
231 return response;
232}
233
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600234Response Handler::setStateEffecterStates(const pldm_msg* request,
235 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500236{
237 Response response(
238 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
239 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
240 uint16_t effecterId;
241 uint8_t compEffecterCnt;
242 constexpr auto maxCompositeEffecterCnt = 8;
243 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
244 {0, 0});
245
246 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
247 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
248 sizeof(set_effecter_state_field)))
249 {
George Liufb8611d2019-12-06 10:14:15 +0800250 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500251 }
252
253 int rc = decode_set_state_effecter_states_req(request, payloadLength,
254 &effecterId, &compEffecterCnt,
255 stateField.data());
256
George Liufb8611d2019-12-06 10:14:15 +0800257 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500258 {
George Liufb8611d2019-12-06 10:14:15 +0800259 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500260 }
261
George Liufb8611d2019-12-06 10:14:15 +0800262 stateField.resize(compEffecterCnt);
263 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500264 uint16_t entityType{};
265 uint16_t entityInstance{};
266 uint16_t stateSetId{};
267
268 if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
269 entityInstance, stateSetId) &&
270 oemPlatformHandler != nullptr)
271 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500272 rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
Varsha Kaverappa3fbd39e2020-09-28 01:40:22 -0500273 entityType, entityInstance, stateSetId, compEffecterCnt, stateField,
274 effecterId);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500275 }
276 else
277 {
278 rc = platform_state_effecter::setStateEffecterStatesHandler<
279 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
280 stateField);
281 }
George Liufb8611d2019-12-06 10:14:15 +0800282 if (rc != PLDM_SUCCESS)
283 {
284 return CmdHandler::ccOnlyResponse(request, rc);
285 }
286
287 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
288 responsePtr);
289 if (rc != PLDM_SUCCESS)
290 {
291 return ccOnlyResponse(request, rc);
292 }
293
Sampa Misraa2fa0702019-05-31 01:28:55 -0500294 return response;
295}
296
Tom Joseph56e45c52020-03-16 10:01:45 +0530297Response Handler::platformEventMessage(const pldm_msg* request,
298 size_t payloadLength)
299{
300 uint8_t formatVersion{};
301 uint8_t tid{};
302 uint8_t eventClass{};
303 size_t offset{};
304
305 auto rc = decode_platform_event_message_req(
306 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
307 if (rc != PLDM_SUCCESS)
308 {
309 return CmdHandler::ccOnlyResponse(request, rc);
310 }
311
312 try
313 {
314 const auto& handlers = eventHandlers.at(eventClass);
315 for (const auto& handler : handlers)
316 {
317 auto rc =
318 handler(request, payloadLength, formatVersion, tid, offset);
319 if (rc != PLDM_SUCCESS)
320 {
321 return CmdHandler::ccOnlyResponse(request, rc);
322 }
323 }
324 }
325 catch (const std::out_of_range& e)
326 {
327 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
328 }
329
330 Response response(
331 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
332 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
333
334 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
335 PLDM_EVENT_NO_LOGGING, responsePtr);
336 if (rc != PLDM_SUCCESS)
337 {
338 return ccOnlyResponse(request, rc);
339 }
340
341 return response;
342}
343
344int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
Tom Josephc4959c32020-04-20 19:50:16 +0530345 uint8_t /*formatVersion*/, uint8_t tid,
Tom Joseph56e45c52020-03-16 10:01:45 +0530346 size_t eventDataOffset)
347{
348 uint16_t sensorId{};
349 uint8_t eventClass{};
350 size_t eventClassDataOffset{};
351 auto eventData =
352 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
353 auto eventDataSize = payloadLength - eventDataOffset;
354
355 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
356 &eventClass, &eventClassDataOffset);
357 if (rc != PLDM_SUCCESS)
358 {
359 return rc;
360 }
361
Zahed Hossain75330f32020-03-24 02:15:03 -0500362 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
363 eventDataOffset + eventClassDataOffset;
364 auto eventClassDataSize =
365 payloadLength - eventDataOffset - eventClassDataOffset;
366
Tom Joseph56e45c52020-03-16 10:01:45 +0530367 if (eventClass == PLDM_STATE_SENSOR_STATE)
368 {
369 uint8_t sensorOffset{};
370 uint8_t eventState{};
371 uint8_t previousEventState{};
372
Zahed Hossain75330f32020-03-24 02:15:03 -0500373 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530374 &sensorOffset, &eventState,
375 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500376 if (rc != PLDM_SUCCESS)
377 {
378 return PLDM_ERROR;
379 }
380
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800381 // Emitting state sensor event signal
382 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
383 previousEventState);
384
Tom Josephc4959c32020-04-20 19:50:16 +0530385 // If there are no HOST PDR's, there is no further action
386 if (hostPDRHandler == NULL)
387 {
388 return PLDM_SUCCESS;
389 }
390
391 // Handle PLDM events for which PDR is available
392 SensorEntry sensorEntry{tid, sensorId};
Tom Josephb70a1962020-07-13 12:56:31 +0530393
394 pldm::pdr::EntityInfo entityInfo{};
395 pldm::pdr::CompositeSensorStates compositeSensorStates{};
396
Tom Josephc4959c32020-04-20 19:50:16 +0530397 try
398 {
Tom Josephb70a1962020-07-13 12:56:31 +0530399 std::tie(entityInfo, compositeSensorStates) =
Tom Josephc4959c32020-04-20 19:50:16 +0530400 hostPDRHandler->lookupSensorInfo(sensorEntry);
Tom Josephc4959c32020-04-20 19:50:16 +0530401 }
Tom Josephc4959c32020-04-20 19:50:16 +0530402 catch (const std::out_of_range& e)
403 {
Tom Josephb70a1962020-07-13 12:56:31 +0530404 // If there is no mapping for tid, sensorId combination, try
405 // PLDM_TID_RESERVED, sensorId for terminus that is yet to
406 // implement TL PDR.
407 try
408 {
409 sensorEntry.terminusID = PLDM_TID_RESERVED;
410 std::tie(entityInfo, compositeSensorStates) =
411 hostPDRHandler->lookupSensorInfo(sensorEntry);
412 }
413 // If there is no mapping for events return PLDM_SUCCESS
414 catch (const std::out_of_range& e)
415 {
416 return PLDM_SUCCESS;
417 }
Zahed Hossain75330f32020-03-24 02:15:03 -0500418 }
Tom Josephb70a1962020-07-13 12:56:31 +0530419
420 if (sensorOffset >= compositeSensorStates.size())
421 {
422 return PLDM_ERROR_INVALID_DATA;
423 }
424
425 const auto& possibleStates = compositeSensorStates[sensorOffset];
426 if (possibleStates.find(eventState) == possibleStates.end())
427 {
428 return PLDM_ERROR_INVALID_DATA;
429 }
430
431 const auto& [containerId, entityType, entityInstance] = entityInfo;
432 events::StateSensorEntry stateSensorEntry{containerId, entityType,
433 entityInstance, sensorOffset};
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600434 return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
435 eventState);
Tom Joseph56e45c52020-03-16 10:01:45 +0530436 }
437 else
438 {
439 return PLDM_ERROR_INVALID_DATA;
440 }
441
442 return PLDM_SUCCESS;
443}
444
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500445int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
446 size_t payloadLength,
447 uint8_t /*formatVersion*/,
448 uint8_t /*tid*/, size_t eventDataOffset)
449{
450 uint8_t eventDataFormat{};
451 uint8_t numberOfChangeRecords{};
452 size_t dataOffset{};
453
454 auto eventData =
455 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
456 auto eventDataSize = payloadLength - eventDataOffset;
457
458 auto rc = decode_pldm_pdr_repository_chg_event_data(
459 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
460 &dataOffset);
461 if (rc != PLDM_SUCCESS)
462 {
463 return rc;
464 }
465
466 PDRRecordHandles pdrRecordHandles;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500467
468 if (eventDataFormat == FORMAT_IS_PDR_TYPES)
469 {
470 return PLDM_ERROR_INVALID_DATA;
471 }
472
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500473 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
474 {
475 uint8_t eventDataOperation{};
476 uint8_t numberOfChangeEntries{};
477
478 auto changeRecordData = eventData + dataOffset;
479 auto changeRecordDataSize = eventDataSize - dataOffset;
480
481 while (changeRecordDataSize)
482 {
483 rc = decode_pldm_pdr_repository_change_record_data(
484 changeRecordData, changeRecordDataSize, &eventDataOperation,
485 &numberOfChangeEntries, &dataOffset);
486
487 if (rc != PLDM_SUCCESS)
488 {
489 return rc;
490 }
491
492 if (eventDataOperation == PLDM_RECORDS_ADDED)
493 {
494 rc = getPDRRecordHandles(
495 reinterpret_cast<const ChangeEntry*>(changeRecordData +
496 dataOffset),
497 changeRecordDataSize - dataOffset,
498 static_cast<size_t>(numberOfChangeEntries),
499 pdrRecordHandles);
500
501 if (rc != PLDM_SUCCESS)
502 {
503 return rc;
504 }
505 }
506
507 changeRecordData +=
508 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
509 changeRecordDataSize -=
510 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
511 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500512 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500513 if (hostPDRHandler)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500514 {
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500515 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500516 }
517
518 return PLDM_SUCCESS;
519}
520
521int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
522 size_t changeEntryDataSize,
523 size_t numberOfChangeEntries,
524 PDRRecordHandles& pdrRecordHandles)
525{
526 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
527 {
528 return PLDM_ERROR_INVALID_DATA;
529 }
530 for (size_t i = 0; i < numberOfChangeEntries; i++)
531 {
532 pdrRecordHandles.push_back(changeEntryData[i]);
533 }
534 return PLDM_SUCCESS;
535}
536
George Liueccb0c52020-01-14 11:09:56 +0800537Response Handler::setNumericEffecterValue(const pldm_msg* request,
538 size_t payloadLength)
539{
540 Response response(sizeof(pldm_msg_hdr) +
541 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
542 uint16_t effecterId{};
543 uint8_t effecterDataSize{};
544 uint8_t effecterValue[4] = {};
545
546 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
547 sizeof(union_effecter_data_size)) ||
548 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
549 {
550 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
551 }
552
553 int rc = decode_set_numeric_effecter_value_req(
554 request, payloadLength, &effecterId, &effecterDataSize,
555 reinterpret_cast<uint8_t*>(&effecterValue));
556
557 if (rc == PLDM_SUCCESS)
558 {
559 const pldm::utils::DBusHandler dBusIntf;
560 rc = platform_numeric_effecter::setNumericEffecterValueHandler<
561 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
562 effecterDataSize, effecterValue,
563 sizeof(effecterValue));
564 }
565
566 return ccOnlyResponse(request, rc);
567}
568
Sampa Misra12afe112020-05-25 11:40:44 -0500569void Handler::generateTerminusLocatorPDR(Repo& repo)
570{
571 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
572
573 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
574
575 pdr->hdr.record_handle = 0;
576 pdr->hdr.version = 1;
577 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
578 pdr->hdr.record_change_num = 0;
579 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
580 pdr->terminus_handle = BmcPldmTerminusHandle;
581 pdr->validity = PLDM_TL_PDR_VALID;
582 pdr->tid = BmcTerminusId;
583 pdr->container_id = 0x0;
584 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
585 pdr->terminus_locator_value_size =
586 sizeof(pldm_terminus_locator_type_mctp_eid);
587 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
588 pdr->terminus_locator_value);
589 locatorValue->eid = BmcMctpEid;
590
591 PdrEntry pdrEntry{};
592 pdrEntry.data = pdrBuffer.data();
593 pdrEntry.size = pdrBuffer.size();
594 repo.addRecord(pdrEntry);
595}
George Liu362c18d2020-05-14 09:46:36 +0800596
597Response Handler::getStateSensorReadings(const pldm_msg* request,
598 size_t payloadLength)
599{
600 uint16_t sensorId{};
601 bitfield8_t sensorRearm{};
602 uint8_t reserved{};
603
604 if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES)
605 {
606 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
607 }
608
609 int rc = decode_get_state_sensor_readings_req(
610 request, payloadLength, &sensorId, &sensorRearm, &reserved);
611
612 if (rc != PLDM_SUCCESS)
613 {
614 return ccOnlyResponse(request, rc);
615 }
616
617 // 0x01 to 0x08
George Liuc1230ca2021-08-03 16:06:50 +0800618 uint8_t sensorRearmCount = std::popcount(sensorRearm.byte);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500619 std::vector<get_sensor_state_field> stateField(sensorRearmCount);
George Liu362c18d2020-05-14 09:46:36 +0800620 uint8_t comSensorCnt{};
621 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500622
623 uint16_t entityType{};
624 uint16_t entityInstance{};
625 uint16_t stateSetId{};
626
627 if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
628 entityType, entityInstance, stateSetId) &&
629 oemPlatformHandler != nullptr)
630 {
631 rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
632 entityType, entityInstance, stateSetId, comSensorCnt, stateField);
633 }
634 else
635 {
636 rc = platform_state_sensor::getStateSensorReadingsHandler<
637 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId,
638 sensorRearmCount, comSensorCnt,
639 stateField);
640 }
George Liu362c18d2020-05-14 09:46:36 +0800641
642 if (rc != PLDM_SUCCESS)
643 {
644 return ccOnlyResponse(request, rc);
645 }
646
647 Response response(sizeof(pldm_msg_hdr) +
648 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
649 sizeof(get_sensor_state_field) * comSensorCnt);
650 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
651 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
652 comSensorCnt, stateField.data(),
653 responsePtr);
654 if (rc != PLDM_SUCCESS)
655 {
656 return ccOnlyResponse(request, rc);
657 }
658
659 return response;
660}
661
Sampa Misra5fb37d52021-03-06 07:26:00 -0600662void Handler::_processPostGetPDRActions(
663 sdeventplus::source::EventBase& /*source */)
664{
665 deferredGetPDREvent.reset();
666 dbusToPLDMEventHandler->listenSensorEvent(pdrRepo, sensorDbusObjMaps);
667}
668
Sampa Misraaea5dde2020-08-31 08:33:47 -0500669bool isOemStateSensor(Handler& handler, uint16_t sensorId,
670 uint8_t sensorRearmCount, uint8_t& compSensorCnt,
671 uint16_t& entityType, uint16_t& entityInstance,
672 uint16_t& stateSetId)
673{
674 pldm_state_sensor_pdr* pdr = nullptr;
675
676 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
677 pldm_pdr_init(), pldm_pdr_destroy);
678 Repo stateSensorPDRs(stateSensorPdrRepo.get());
679 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
680 if (stateSensorPDRs.empty())
681 {
682 std::cerr << "Failed to get record by PDR type\n";
683 return false;
684 }
685
686 PdrEntry pdrEntry{};
687 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
688 while (pdrRecord)
689 {
690 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
691 assert(pdr != NULL);
692 if (pdr->sensor_id != sensorId)
693 {
694 pdr = nullptr;
695 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
696 continue;
697 }
698 auto tmpEntityType = pdr->entity_type;
699 auto tmpEntityInstance = pdr->entity_instance;
700 auto tmpCompSensorCnt = pdr->composite_sensor_count;
701 auto tmpPossibleStates =
702 reinterpret_cast<state_sensor_possible_states*>(
703 pdr->possible_states);
704 auto tmpStateSetId = tmpPossibleStates->state_set_id;
705
706 if (sensorRearmCount > tmpCompSensorCnt)
707 {
708 std::cerr << "The requester sent wrong sensorRearm"
709 << " count for the sensor, SENSOR_ID=" << sensorId
710 << "SENSOR_REARM_COUNT=" << (uint16_t)sensorRearmCount
711 << "\n";
712 break;
713 }
714
715 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
716 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
717 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
718 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
719 {
720 entityType = tmpEntityType;
721 entityInstance = tmpEntityInstance;
722 stateSetId = tmpStateSetId;
723 compSensorCnt = tmpCompSensorCnt;
724 return true;
725 }
726 else
727 {
728 return false;
729 }
730 }
731 return false;
732}
733
734bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
735 uint8_t compEffecterCnt, uint16_t& entityType,
736 uint16_t& entityInstance, uint16_t& stateSetId)
737{
738 pldm_state_effecter_pdr* pdr = nullptr;
739
740 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
741 pldm_pdr_init(), pldm_pdr_destroy);
742 Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
743 getRepoByType(handler.getRepo(), stateEffecterPDRs,
744 PLDM_STATE_EFFECTER_PDR);
745 if (stateEffecterPDRs.empty())
746 {
747 std::cerr << "Failed to get record by PDR type\n";
748 return false;
749 }
750
751 PdrEntry pdrEntry{};
752 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
753 while (pdrRecord)
754 {
755 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
756 assert(pdr != NULL);
757 if (pdr->effecter_id != effecterId)
758 {
759 pdr = nullptr;
760 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
761 continue;
762 }
763
764 auto tmpEntityType = pdr->entity_type;
765 auto tmpEntityInstance = pdr->entity_instance;
766 auto tmpPossibleStates =
767 reinterpret_cast<state_effecter_possible_states*>(
768 pdr->possible_states);
769 auto tmpStateSetId = tmpPossibleStates->state_set_id;
770
771 if (compEffecterCnt > pdr->composite_effecter_count)
772 {
773 std::cerr << "The requester sent wrong composite effecter"
774 << " count for the effecter, EFFECTER_ID=" << effecterId
775 << "COMP_EFF_CNT=" << (uint16_t)compEffecterCnt << "\n";
776 return false;
777 }
778
779 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
780 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
781 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
782 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
783 {
784 entityType = tmpEntityType;
785 entityInstance = tmpEntityInstance;
786 stateSetId = tmpStateSetId;
787 return true;
788 }
789 else
790 {
791 return false;
792 }
793 }
794 return false;
795}
796
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600797} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530798} // namespace responder
799} // namespace pldm