blob: 984d79b1481df0840da0e8433df8614ad83bdcfe [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);
153 pdrCreated = true;
154 }
155
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530156 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
157 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
158
159 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
160 {
George Liufb8611d2019-12-06 10:14:15 +0800161 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530162 }
163
164 uint32_t recordHandle{};
165 uint32_t dataTransferHandle{};
166 uint8_t transferOpFlag{};
167 uint16_t reqSizeBytes{};
168 uint16_t recordChangeNum{};
169
George Liufb8611d2019-12-06 10:14:15 +0800170 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
171 &dataTransferHandle, &transferOpFlag,
172 &reqSizeBytes, &recordChangeNum);
173 if (rc != PLDM_SUCCESS)
174 {
175 return CmdHandler::ccOnlyResponse(request, rc);
176 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530177
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530178 uint16_t respSizeBytes{};
179 uint8_t* recordData = nullptr;
180 try
181 {
George Liue53193f2020-02-24 09:23:26 +0800182 pdr_utils::PdrEntry e;
183 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
184 if (record == NULL)
185 {
186 return CmdHandler::ccOnlyResponse(
187 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
188 }
189
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530190 if (reqSizeBytes)
191 {
George Liue53193f2020-02-24 09:23:26 +0800192 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530193 if (respSizeBytes > reqSizeBytes)
194 {
195 respSizeBytes = reqSizeBytes;
196 }
George Liue53193f2020-02-24 09:23:26 +0800197 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530198 }
199 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
200 respSizeBytes,
201 0);
202 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500203 rc = encode_get_pdr_resp(
204 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
205 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800206 if (rc != PLDM_SUCCESS)
207 {
208 return ccOnlyResponse(request, rc);
209 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530210 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530211 catch (const std::exception& e)
212 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600213 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
214 << " ERROR=" << e.what() << "\n";
George Liufb8611d2019-12-06 10:14:15 +0800215 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530216 }
217 return response;
218}
219
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600220Response Handler::setStateEffecterStates(const pldm_msg* request,
221 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500222{
223 Response response(
224 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
225 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
226 uint16_t effecterId;
227 uint8_t compEffecterCnt;
228 constexpr auto maxCompositeEffecterCnt = 8;
229 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
230 {0, 0});
231
232 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
233 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
234 sizeof(set_effecter_state_field)))
235 {
George Liufb8611d2019-12-06 10:14:15 +0800236 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500237 }
238
239 int rc = decode_set_state_effecter_states_req(request, payloadLength,
240 &effecterId, &compEffecterCnt,
241 stateField.data());
242
George Liufb8611d2019-12-06 10:14:15 +0800243 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500244 {
George Liufb8611d2019-12-06 10:14:15 +0800245 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500246 }
247
George Liufb8611d2019-12-06 10:14:15 +0800248 stateField.resize(compEffecterCnt);
249 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500250 uint16_t entityType{};
251 uint16_t entityInstance{};
252 uint16_t stateSetId{};
253
254 if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
255 entityInstance, stateSetId) &&
256 oemPlatformHandler != nullptr)
257 {
258 rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
259 entityType, entityInstance, stateSetId, compEffecterCnt,
260 stateField);
261 }
262 else
263 {
264 rc = platform_state_effecter::setStateEffecterStatesHandler<
265 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
266 stateField);
267 }
George Liufb8611d2019-12-06 10:14:15 +0800268 if (rc != PLDM_SUCCESS)
269 {
270 return CmdHandler::ccOnlyResponse(request, rc);
271 }
272
273 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
274 responsePtr);
275 if (rc != PLDM_SUCCESS)
276 {
277 return ccOnlyResponse(request, rc);
278 }
279
Sampa Misraa2fa0702019-05-31 01:28:55 -0500280 return response;
281}
282
Tom Joseph56e45c52020-03-16 10:01:45 +0530283Response Handler::platformEventMessage(const pldm_msg* request,
284 size_t payloadLength)
285{
286 uint8_t formatVersion{};
287 uint8_t tid{};
288 uint8_t eventClass{};
289 size_t offset{};
290
291 auto rc = decode_platform_event_message_req(
292 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
293 if (rc != PLDM_SUCCESS)
294 {
295 return CmdHandler::ccOnlyResponse(request, rc);
296 }
297
298 try
299 {
300 const auto& handlers = eventHandlers.at(eventClass);
301 for (const auto& handler : handlers)
302 {
303 auto rc =
304 handler(request, payloadLength, formatVersion, tid, offset);
305 if (rc != PLDM_SUCCESS)
306 {
307 return CmdHandler::ccOnlyResponse(request, rc);
308 }
309 }
310 }
311 catch (const std::out_of_range& e)
312 {
313 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
314 }
315
316 Response response(
317 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
318 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
319
320 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
321 PLDM_EVENT_NO_LOGGING, responsePtr);
322 if (rc != PLDM_SUCCESS)
323 {
324 return ccOnlyResponse(request, rc);
325 }
326
327 return response;
328}
329
330int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
Tom Josephc4959c32020-04-20 19:50:16 +0530331 uint8_t /*formatVersion*/, uint8_t tid,
Tom Joseph56e45c52020-03-16 10:01:45 +0530332 size_t eventDataOffset)
333{
334 uint16_t sensorId{};
335 uint8_t eventClass{};
336 size_t eventClassDataOffset{};
337 auto eventData =
338 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
339 auto eventDataSize = payloadLength - eventDataOffset;
340
341 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
342 &eventClass, &eventClassDataOffset);
343 if (rc != PLDM_SUCCESS)
344 {
345 return rc;
346 }
347
Zahed Hossain75330f32020-03-24 02:15:03 -0500348 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
349 eventDataOffset + eventClassDataOffset;
350 auto eventClassDataSize =
351 payloadLength - eventDataOffset - eventClassDataOffset;
352
Tom Joseph56e45c52020-03-16 10:01:45 +0530353 if (eventClass == PLDM_STATE_SENSOR_STATE)
354 {
355 uint8_t sensorOffset{};
356 uint8_t eventState{};
357 uint8_t previousEventState{};
358
Zahed Hossain75330f32020-03-24 02:15:03 -0500359 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530360 &sensorOffset, &eventState,
361 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500362 if (rc != PLDM_SUCCESS)
363 {
364 return PLDM_ERROR;
365 }
366
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800367 // Emitting state sensor event signal
368 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
369 previousEventState);
370
Tom Josephc4959c32020-04-20 19:50:16 +0530371 // If there are no HOST PDR's, there is no further action
372 if (hostPDRHandler == NULL)
373 {
374 return PLDM_SUCCESS;
375 }
376
377 // Handle PLDM events for which PDR is available
378 SensorEntry sensorEntry{tid, sensorId};
Tom Josephb70a1962020-07-13 12:56:31 +0530379
380 pldm::pdr::EntityInfo entityInfo{};
381 pldm::pdr::CompositeSensorStates compositeSensorStates{};
382
Tom Josephc4959c32020-04-20 19:50:16 +0530383 try
384 {
Tom Josephb70a1962020-07-13 12:56:31 +0530385 std::tie(entityInfo, compositeSensorStates) =
Tom Josephc4959c32020-04-20 19:50:16 +0530386 hostPDRHandler->lookupSensorInfo(sensorEntry);
Tom Josephc4959c32020-04-20 19:50:16 +0530387 }
Tom Josephc4959c32020-04-20 19:50:16 +0530388 catch (const std::out_of_range& e)
389 {
Tom Josephb70a1962020-07-13 12:56:31 +0530390 // If there is no mapping for tid, sensorId combination, try
391 // PLDM_TID_RESERVED, sensorId for terminus that is yet to
392 // implement TL PDR.
393 try
394 {
395 sensorEntry.terminusID = PLDM_TID_RESERVED;
396 std::tie(entityInfo, compositeSensorStates) =
397 hostPDRHandler->lookupSensorInfo(sensorEntry);
398 }
399 // If there is no mapping for events return PLDM_SUCCESS
400 catch (const std::out_of_range& e)
401 {
402 return PLDM_SUCCESS;
403 }
Zahed Hossain75330f32020-03-24 02:15:03 -0500404 }
Tom Josephb70a1962020-07-13 12:56:31 +0530405
406 if (sensorOffset >= compositeSensorStates.size())
407 {
408 return PLDM_ERROR_INVALID_DATA;
409 }
410
411 const auto& possibleStates = compositeSensorStates[sensorOffset];
412 if (possibleStates.find(eventState) == possibleStates.end())
413 {
414 return PLDM_ERROR_INVALID_DATA;
415 }
416
417 const auto& [containerId, entityType, entityInstance] = entityInfo;
418 events::StateSensorEntry stateSensorEntry{containerId, entityType,
419 entityInstance, sensorOffset};
Pavithra Barithaya3aec9972020-12-14 01:55:44 -0600420 return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
421 eventState);
Tom Joseph56e45c52020-03-16 10:01:45 +0530422 }
423 else
424 {
425 return PLDM_ERROR_INVALID_DATA;
426 }
427
428 return PLDM_SUCCESS;
429}
430
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500431int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
432 size_t payloadLength,
433 uint8_t /*formatVersion*/,
434 uint8_t /*tid*/, size_t eventDataOffset)
435{
436 uint8_t eventDataFormat{};
437 uint8_t numberOfChangeRecords{};
438 size_t dataOffset{};
439
440 auto eventData =
441 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
442 auto eventDataSize = payloadLength - eventDataOffset;
443
444 auto rc = decode_pldm_pdr_repository_chg_event_data(
445 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
446 &dataOffset);
447 if (rc != PLDM_SUCCESS)
448 {
449 return rc;
450 }
451
452 PDRRecordHandles pdrRecordHandles;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500453
454 if (eventDataFormat == FORMAT_IS_PDR_TYPES)
455 {
456 return PLDM_ERROR_INVALID_DATA;
457 }
458
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500459 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
460 {
461 uint8_t eventDataOperation{};
462 uint8_t numberOfChangeEntries{};
463
464 auto changeRecordData = eventData + dataOffset;
465 auto changeRecordDataSize = eventDataSize - dataOffset;
466
467 while (changeRecordDataSize)
468 {
469 rc = decode_pldm_pdr_repository_change_record_data(
470 changeRecordData, changeRecordDataSize, &eventDataOperation,
471 &numberOfChangeEntries, &dataOffset);
472
473 if (rc != PLDM_SUCCESS)
474 {
475 return rc;
476 }
477
478 if (eventDataOperation == PLDM_RECORDS_ADDED)
479 {
480 rc = getPDRRecordHandles(
481 reinterpret_cast<const ChangeEntry*>(changeRecordData +
482 dataOffset),
483 changeRecordDataSize - dataOffset,
484 static_cast<size_t>(numberOfChangeEntries),
485 pdrRecordHandles);
486
487 if (rc != PLDM_SUCCESS)
488 {
489 return rc;
490 }
491 }
492
493 changeRecordData +=
494 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
495 changeRecordDataSize -=
496 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
497 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500498 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500499 if (hostPDRHandler)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500500 {
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500501 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500502 }
503
504 return PLDM_SUCCESS;
505}
506
507int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
508 size_t changeEntryDataSize,
509 size_t numberOfChangeEntries,
510 PDRRecordHandles& pdrRecordHandles)
511{
512 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
513 {
514 return PLDM_ERROR_INVALID_DATA;
515 }
516 for (size_t i = 0; i < numberOfChangeEntries; i++)
517 {
518 pdrRecordHandles.push_back(changeEntryData[i]);
519 }
520 return PLDM_SUCCESS;
521}
522
George Liueccb0c52020-01-14 11:09:56 +0800523Response Handler::setNumericEffecterValue(const pldm_msg* request,
524 size_t payloadLength)
525{
526 Response response(sizeof(pldm_msg_hdr) +
527 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
528 uint16_t effecterId{};
529 uint8_t effecterDataSize{};
530 uint8_t effecterValue[4] = {};
531
532 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
533 sizeof(union_effecter_data_size)) ||
534 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
535 {
536 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
537 }
538
539 int rc = decode_set_numeric_effecter_value_req(
540 request, payloadLength, &effecterId, &effecterDataSize,
541 reinterpret_cast<uint8_t*>(&effecterValue));
542
543 if (rc == PLDM_SUCCESS)
544 {
545 const pldm::utils::DBusHandler dBusIntf;
546 rc = platform_numeric_effecter::setNumericEffecterValueHandler<
547 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
548 effecterDataSize, effecterValue,
549 sizeof(effecterValue));
550 }
551
552 return ccOnlyResponse(request, rc);
553}
554
Sampa Misra12afe112020-05-25 11:40:44 -0500555void Handler::generateTerminusLocatorPDR(Repo& repo)
556{
557 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
558
559 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
560
561 pdr->hdr.record_handle = 0;
562 pdr->hdr.version = 1;
563 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
564 pdr->hdr.record_change_num = 0;
565 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
566 pdr->terminus_handle = BmcPldmTerminusHandle;
567 pdr->validity = PLDM_TL_PDR_VALID;
568 pdr->tid = BmcTerminusId;
569 pdr->container_id = 0x0;
570 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
571 pdr->terminus_locator_value_size =
572 sizeof(pldm_terminus_locator_type_mctp_eid);
573 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
574 pdr->terminus_locator_value);
575 locatorValue->eid = BmcMctpEid;
576
577 PdrEntry pdrEntry{};
578 pdrEntry.data = pdrBuffer.data();
579 pdrEntry.size = pdrBuffer.size();
580 repo.addRecord(pdrEntry);
581}
George Liu362c18d2020-05-14 09:46:36 +0800582
583Response Handler::getStateSensorReadings(const pldm_msg* request,
584 size_t payloadLength)
585{
586 uint16_t sensorId{};
587 bitfield8_t sensorRearm{};
588 uint8_t reserved{};
589
590 if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES)
591 {
592 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
593 }
594
595 int rc = decode_get_state_sensor_readings_req(
596 request, payloadLength, &sensorId, &sensorRearm, &reserved);
597
598 if (rc != PLDM_SUCCESS)
599 {
600 return ccOnlyResponse(request, rc);
601 }
602
603 // 0x01 to 0x08
Sampa Misraaea5dde2020-08-31 08:33:47 -0500604 uint8_t sensorRearmCount = getBitfieldCount(sensorRearm);
605 std::vector<get_sensor_state_field> stateField(sensorRearmCount);
George Liu362c18d2020-05-14 09:46:36 +0800606 uint8_t comSensorCnt{};
607 const pldm::utils::DBusHandler dBusIntf;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500608
609 uint16_t entityType{};
610 uint16_t entityInstance{};
611 uint16_t stateSetId{};
612
613 if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
614 entityType, entityInstance, stateSetId) &&
615 oemPlatformHandler != nullptr)
616 {
617 rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
618 entityType, entityInstance, stateSetId, comSensorCnt, stateField);
619 }
620 else
621 {
622 rc = platform_state_sensor::getStateSensorReadingsHandler<
623 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId,
624 sensorRearmCount, comSensorCnt,
625 stateField);
626 }
George Liu362c18d2020-05-14 09:46:36 +0800627
628 if (rc != PLDM_SUCCESS)
629 {
630 return ccOnlyResponse(request, rc);
631 }
632
633 Response response(sizeof(pldm_msg_hdr) +
634 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
635 sizeof(get_sensor_state_field) * comSensorCnt);
636 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
637 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
638 comSensorCnt, stateField.data(),
639 responsePtr);
640 if (rc != PLDM_SUCCESS)
641 {
642 return ccOnlyResponse(request, rc);
643 }
644
645 return response;
646}
647
Sampa Misraaea5dde2020-08-31 08:33:47 -0500648bool isOemStateSensor(Handler& handler, uint16_t sensorId,
649 uint8_t sensorRearmCount, uint8_t& compSensorCnt,
650 uint16_t& entityType, uint16_t& entityInstance,
651 uint16_t& stateSetId)
652{
653 pldm_state_sensor_pdr* pdr = nullptr;
654
655 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
656 pldm_pdr_init(), pldm_pdr_destroy);
657 Repo stateSensorPDRs(stateSensorPdrRepo.get());
658 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
659 if (stateSensorPDRs.empty())
660 {
661 std::cerr << "Failed to get record by PDR type\n";
662 return false;
663 }
664
665 PdrEntry pdrEntry{};
666 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
667 while (pdrRecord)
668 {
669 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
670 assert(pdr != NULL);
671 if (pdr->sensor_id != sensorId)
672 {
673 pdr = nullptr;
674 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
675 continue;
676 }
677 auto tmpEntityType = pdr->entity_type;
678 auto tmpEntityInstance = pdr->entity_instance;
679 auto tmpCompSensorCnt = pdr->composite_sensor_count;
680 auto tmpPossibleStates =
681 reinterpret_cast<state_sensor_possible_states*>(
682 pdr->possible_states);
683 auto tmpStateSetId = tmpPossibleStates->state_set_id;
684
685 if (sensorRearmCount > tmpCompSensorCnt)
686 {
687 std::cerr << "The requester sent wrong sensorRearm"
688 << " count for the sensor, SENSOR_ID=" << sensorId
689 << "SENSOR_REARM_COUNT=" << (uint16_t)sensorRearmCount
690 << "\n";
691 break;
692 }
693
694 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
695 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
696 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
697 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
698 {
699 entityType = tmpEntityType;
700 entityInstance = tmpEntityInstance;
701 stateSetId = tmpStateSetId;
702 compSensorCnt = tmpCompSensorCnt;
703 return true;
704 }
705 else
706 {
707 return false;
708 }
709 }
710 return false;
711}
712
713bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
714 uint8_t compEffecterCnt, uint16_t& entityType,
715 uint16_t& entityInstance, uint16_t& stateSetId)
716{
717 pldm_state_effecter_pdr* pdr = nullptr;
718
719 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
720 pldm_pdr_init(), pldm_pdr_destroy);
721 Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
722 getRepoByType(handler.getRepo(), stateEffecterPDRs,
723 PLDM_STATE_EFFECTER_PDR);
724 if (stateEffecterPDRs.empty())
725 {
726 std::cerr << "Failed to get record by PDR type\n";
727 return false;
728 }
729
730 PdrEntry pdrEntry{};
731 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
732 while (pdrRecord)
733 {
734 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
735 assert(pdr != NULL);
736 if (pdr->effecter_id != effecterId)
737 {
738 pdr = nullptr;
739 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
740 continue;
741 }
742
743 auto tmpEntityType = pdr->entity_type;
744 auto tmpEntityInstance = pdr->entity_instance;
745 auto tmpPossibleStates =
746 reinterpret_cast<state_effecter_possible_states*>(
747 pdr->possible_states);
748 auto tmpStateSetId = tmpPossibleStates->state_set_id;
749
750 if (compEffecterCnt > pdr->composite_effecter_count)
751 {
752 std::cerr << "The requester sent wrong composite effecter"
753 << " count for the effecter, EFFECTER_ID=" << effecterId
754 << "COMP_EFF_CNT=" << (uint16_t)compEffecterCnt << "\n";
755 return false;
756 }
757
758 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
759 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
760 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
761 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
762 {
763 entityType = tmpEntityType;
764 entityInstance = tmpEntityInstance;
765 stateSetId = tmpStateSetId;
766 return true;
767 }
768 else
769 {
770 return false;
771 }
772 }
773 return false;
774}
775
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600776} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530777} // namespace responder
778} // namespace pldm