blob: dff2352ebd9bf30bf564023548b1ba5844cbfbff [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301
2#include "platform.hpp"
3
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
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053015namespace pldm
16{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053017namespace responder
18{
Sampa Misraa2fa0702019-05-31 01:28:55 -050019namespace platform
20{
21
Deepak Kodihallic682fe22020-03-04 00:42:54 -060022using InternalFailure =
23 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
24
George Liu1ec85d42020-02-12 16:05:32 +080025static const Json empty{};
26
Zahed Hossain75330f32020-03-24 02:15:03 -050027using EventEntryMap = std::map<EventEntry, DBusInfo>;
28
29const EventEntryMap eventEntryMap = {
30 {
31 0x01010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
32 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
33 // (Valid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053034 {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050035 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
36 },
37 {
38 0x02010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
39 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
40 // (Invalid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053041 {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050042 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
43 },
44 {
45 0x01010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
46 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
47 // (Valid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053048 {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050049 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
50 },
51 {
52 0x02010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
53 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
54 // (Invalid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053055 {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050056 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
57 }};
58
George Liua2870722020-02-11 11:09:30 +080059void Handler::addDbusObjMaps(
George Liuadbe1722020-05-09 19:20:19 +080060 uint16_t id,
61 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
62 TypeId typeId)
George Liu1ec85d42020-02-12 16:05:32 +080063{
George Liuadbe1722020-05-09 19:20:19 +080064 if (typeId == TypeId::PLDM_SENSOR_ID)
65 {
66 sensorDbusObjMaps.emplace(id, dbusObj);
67 }
68 else
69 {
70 effecterDbusObjMaps.emplace(id, dbusObj);
71 }
George Liu1ec85d42020-02-12 16:05:32 +080072}
73
George Liua2870722020-02-11 11:09:30 +080074const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liuadbe1722020-05-09 19:20:19 +080075 Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
George Liu1ec85d42020-02-12 16:05:32 +080076{
George Liuadbe1722020-05-09 19:20:19 +080077 if (typeId == TypeId::PLDM_SENSOR_ID)
78 {
79 return sensorDbusObjMaps.at(id);
80 }
81 else
82 {
83 return effecterDbusObjMaps.at(id);
84 }
George Liu1ec85d42020-02-12 16:05:32 +080085}
86
George Liu36e81352020-07-01 14:40:30 +080087void Handler::generate(const pldm::utils::DBusHandler& dBusIntf,
88 const std::string& dir, Repo& repo)
Deepak Kodihallic682fe22020-03-04 00:42:54 -060089{
Deepak Kodihallic6e49c42020-07-01 03:39:27 -050090 if (!fs::exists(dir))
91 {
92 return;
93 }
94
Deepak Kodihallic682fe22020-03-04 00:42:54 -060095 // A map of PDR type to a lambda that handles creation of that PDR type.
96 // The lambda essentially would parse the platform specific PDR JSONs to
97 // generate the PDR structures. This function iterates through the map to
98 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080099
100 const std::map<Type, generatePDR> generateHandlers = {
101 {PLDM_STATE_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +0800102 [this](const DBusHandler& dBusIntf, const auto& json,
103 RepoInterface& repo) {
104 pdr_state_effecter::generateStateEffecterPDR<
105 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
106 repo);
George Liu456c9a22020-01-13 11:36:22 +0800107 }},
108 {PLDM_NUMERIC_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +0800109 [this](const DBusHandler& dBusIntf, const auto& json,
110 RepoInterface& repo) {
111 pdr_numeric_effecter::generateNumericEffecterPDR<
112 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
113 repo);
George Liuadbe1722020-05-09 19:20:19 +0800114 }},
115 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf,
116 const auto& json, RepoInterface& repo) {
117 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler,
118 Handler>(dBusIntf, json,
119 *this, repo);
George Liua2870722020-02-11 11:09:30 +0800120 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600121
122 Type pdrType{};
123 for (const auto& dirEntry : fs::directory_iterator(dir))
124 {
125 try
126 {
127 auto json = readJson(dirEntry.path().string());
128 if (!json.empty())
129 {
George Liu1ec85d42020-02-12 16:05:32 +0800130 auto effecterPDRs = json.value("effecterPDRs", empty);
131 for (const auto& effecter : effecterPDRs)
132 {
133 pdrType = effecter.value("pdrType", 0);
George Liu36e81352020-07-01 14:40:30 +0800134 generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +0800135 }
George Liuadbe1722020-05-09 19:20:19 +0800136
137 auto sensorPDRs = json.value("sensorPDRs", empty);
138 for (const auto& sensor : sensorPDRs)
139 {
140 pdrType = sensor.value("pdrType", 0);
141 generateHandlers.at(pdrType)(dBusIntf, sensor, repo);
142 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600143 }
144 }
145 catch (const InternalFailure& e)
146 {
147 std::cerr << "PDR config directory does not exist or empty, TYPE= "
148 << pdrType << "PATH= " << dirEntry
149 << " ERROR=" << e.what() << "\n";
150 }
151 catch (const Json::exception& e)
152 {
153 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
154 << " ERROR=" << e.what() << "\n";
155 pldm::utils::reportError(
156 "xyz.openbmc_project.bmc.pldm.InternalFailure");
157 }
158 catch (const std::exception& e)
159 {
160 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
161 << " ERROR=" << e.what() << "\n";
162 pldm::utils::reportError(
163 "xyz.openbmc_project.bmc.pldm.InternalFailure");
164 }
165 }
166}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530167
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600168Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530169{
Deepak Kodihallib5c227e2020-07-13 06:58:34 -0500170 if (!pdrCreated)
171 {
Sampa Misra12afe112020-05-25 11:40:44 -0500172 generateTerminusLocatorPDR(pdrRepo);
Deepak Kodihallib5c227e2020-07-13 06:58:34 -0500173 generate(*dBusIntf, pdrJsonsDir, pdrRepo);
174 pdrCreated = true;
George Liucae18662020-05-15 09:32:57 +0800175
176 if (dbusToPLDMEventHandler)
177 {
178 dbusToPLDMEventHandler->listenSensorEvent(pdrRepo,
179 sensorDbusObjMaps);
180 }
Deepak Kodihallib5c227e2020-07-13 06:58:34 -0500181 }
182
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530183 // Build FRU table if not built, since entity association PDR's are built
184 // when the FRU table is constructed.
185 if (fruHandler)
186 {
187 fruHandler->buildFRUTable();
188 }
189
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530190 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
191 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
192
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);
236 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 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600247 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
248 << " ERROR=" << e.what() << "\n";
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;
George Liu0d7aca82020-03-30 15:01:36 +0800284 rc = platform_state_effecter::setStateEffecterStatesHandler<
285 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
286 stateField);
George Liufb8611d2019-12-06 10:14:15 +0800287 if (rc != PLDM_SUCCESS)
288 {
289 return CmdHandler::ccOnlyResponse(request, rc);
290 }
291
292 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
293 responsePtr);
294 if (rc != PLDM_SUCCESS)
295 {
296 return ccOnlyResponse(request, rc);
297 }
298
Sampa Misraa2fa0702019-05-31 01:28:55 -0500299 return response;
300}
301
Tom Joseph56e45c52020-03-16 10:01:45 +0530302Response Handler::platformEventMessage(const pldm_msg* request,
303 size_t payloadLength)
304{
305 uint8_t formatVersion{};
306 uint8_t tid{};
307 uint8_t eventClass{};
308 size_t offset{};
309
310 auto rc = decode_platform_event_message_req(
311 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
312 if (rc != PLDM_SUCCESS)
313 {
314 return CmdHandler::ccOnlyResponse(request, rc);
315 }
316
317 try
318 {
319 const auto& handlers = eventHandlers.at(eventClass);
320 for (const auto& handler : handlers)
321 {
322 auto rc =
323 handler(request, payloadLength, formatVersion, tid, offset);
324 if (rc != PLDM_SUCCESS)
325 {
326 return CmdHandler::ccOnlyResponse(request, rc);
327 }
328 }
329 }
330 catch (const std::out_of_range& e)
331 {
332 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
333 }
334
335 Response response(
336 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
337 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
338
339 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
340 PLDM_EVENT_NO_LOGGING, responsePtr);
341 if (rc != PLDM_SUCCESS)
342 {
343 return ccOnlyResponse(request, rc);
344 }
345
346 return response;
347}
348
349int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
Tom Josephc4959c32020-04-20 19:50:16 +0530350 uint8_t /*formatVersion*/, uint8_t tid,
Tom Joseph56e45c52020-03-16 10:01:45 +0530351 size_t eventDataOffset)
352{
353 uint16_t sensorId{};
354 uint8_t eventClass{};
355 size_t eventClassDataOffset{};
356 auto eventData =
357 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
358 auto eventDataSize = payloadLength - eventDataOffset;
359
360 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
361 &eventClass, &eventClassDataOffset);
362 if (rc != PLDM_SUCCESS)
363 {
364 return rc;
365 }
366
Zahed Hossain75330f32020-03-24 02:15:03 -0500367 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
368 eventDataOffset + eventClassDataOffset;
369 auto eventClassDataSize =
370 payloadLength - eventDataOffset - eventClassDataOffset;
371
Tom Joseph56e45c52020-03-16 10:01:45 +0530372 if (eventClass == PLDM_STATE_SENSOR_STATE)
373 {
374 uint8_t sensorOffset{};
375 uint8_t eventState{};
376 uint8_t previousEventState{};
377
Zahed Hossain75330f32020-03-24 02:15:03 -0500378 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530379 &sensorOffset, &eventState,
380 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500381 if (rc != PLDM_SUCCESS)
382 {
383 return PLDM_ERROR;
384 }
385
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800386 // Emitting state sensor event signal
387 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
388 previousEventState);
389
Tom Josephc4959c32020-04-20 19:50:16 +0530390 // Handle PLDM events for which PDR is not available, setSensorEventData
391 // will return PLDM_ERROR_INVALID_DATA if the sensorID is not found in
392 // the hardcoded sensor list.
Zahed Hossain75330f32020-03-24 02:15:03 -0500393 rc = setSensorEventData(sensorId, sensorOffset, eventState);
Tom Josephc4959c32020-04-20 19:50:16 +0530394 if (rc != PLDM_ERROR_INVALID_DATA)
Zahed Hossain75330f32020-03-24 02:15:03 -0500395 {
Tom Josephc4959c32020-04-20 19:50:16 +0530396 return rc;
397 }
398
399 // If there are no HOST PDR's, there is no further action
400 if (hostPDRHandler == NULL)
401 {
402 return PLDM_SUCCESS;
403 }
404
405 // Handle PLDM events for which PDR is available
406 SensorEntry sensorEntry{tid, sensorId};
407 try
408 {
409 const auto& [entityInfo, compositeSensorStates] =
410 hostPDRHandler->lookupSensorInfo(sensorEntry);
411 if (sensorOffset >= compositeSensorStates.size())
412 {
413 return PLDM_ERROR_INVALID_DATA;
414 }
415
416 const auto& possibleStates = compositeSensorStates[sensorOffset];
417 if (possibleStates.find(eventState) == possibleStates.end())
418 {
419 return PLDM_ERROR_INVALID_DATA;
420 }
421
422 const auto& [containerId, entityType, entityInstance] = entityInfo;
423 events::StateSensorEntry stateSensorEntry{
424 containerId, entityType, entityInstance, sensorOffset};
425 return stateSensorHandler.eventAction(stateSensorEntry, eventState);
426 }
427 // If there is no mapping for events return PLDM_SUCCESS
428 catch (const std::out_of_range& e)
429 {
430 return PLDM_SUCCESS;
Zahed Hossain75330f32020-03-24 02:15:03 -0500431 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530432 }
433 else
434 {
435 return PLDM_ERROR_INVALID_DATA;
436 }
437
438 return PLDM_SUCCESS;
439}
440
Zahed Hossain75330f32020-03-24 02:15:03 -0500441int Handler::setSensorEventData(uint16_t sensorId, uint8_t sensorOffset,
442 uint8_t eventState)
443{
444 EventEntry eventEntry = ((static_cast<uint32_t>(eventState)) << 24) +
445 ((static_cast<uint32_t>(sensorOffset)) << 16) +
446 sensorId;
447 auto iter = eventEntryMap.find(eventEntry);
448 if (iter == eventEntryMap.end())
449 {
Tom Josephc4959c32020-04-20 19:50:16 +0530450 return PLDM_ERROR_INVALID_DATA;
Zahed Hossain75330f32020-03-24 02:15:03 -0500451 }
452
453 const auto& dBusInfo = iter->second;
454 try
455 {
456 pldm::utils::DBusMapping dbusMapping{
457 dBusInfo.dBusValues.objectPath, dBusInfo.dBusValues.interface,
458 dBusInfo.dBusValues.propertyName, dBusInfo.dBusValues.propertyType};
459 pldm::utils::DBusHandler().setDbusProperty(dbusMapping,
460 dBusInfo.dBusPropertyValue);
461 }
462 catch (std::exception& e)
463 {
Zahed Hossain75330f32020-03-24 02:15:03 -0500464 std::cerr
465 << "Error Setting dbus property,SensorID=" << eventEntry
466 << "DBusInfo=" << dBusInfo.dBusValues.objectPath
467 << dBusInfo.dBusValues.interface << dBusInfo.dBusValues.propertyName
468 << "ERROR=" << e.what() << "\n";
469 return PLDM_ERROR;
470 }
471 return PLDM_SUCCESS;
472}
473
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500474int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
475 size_t payloadLength,
476 uint8_t /*formatVersion*/,
477 uint8_t /*tid*/, size_t eventDataOffset)
478{
479 uint8_t eventDataFormat{};
480 uint8_t numberOfChangeRecords{};
481 size_t dataOffset{};
482
483 auto eventData =
484 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
485 auto eventDataSize = payloadLength - eventDataOffset;
486
487 auto rc = decode_pldm_pdr_repository_chg_event_data(
488 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
489 &dataOffset);
490 if (rc != PLDM_SUCCESS)
491 {
492 return rc;
493 }
494
495 PDRRecordHandles pdrRecordHandles;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500496
497 if (eventDataFormat == FORMAT_IS_PDR_TYPES)
498 {
499 return PLDM_ERROR_INVALID_DATA;
500 }
501
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500502 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
503 {
504 uint8_t eventDataOperation{};
505 uint8_t numberOfChangeEntries{};
506
507 auto changeRecordData = eventData + dataOffset;
508 auto changeRecordDataSize = eventDataSize - dataOffset;
509
510 while (changeRecordDataSize)
511 {
512 rc = decode_pldm_pdr_repository_change_record_data(
513 changeRecordData, changeRecordDataSize, &eventDataOperation,
514 &numberOfChangeEntries, &dataOffset);
515
516 if (rc != PLDM_SUCCESS)
517 {
518 return rc;
519 }
520
521 if (eventDataOperation == PLDM_RECORDS_ADDED)
522 {
523 rc = getPDRRecordHandles(
524 reinterpret_cast<const ChangeEntry*>(changeRecordData +
525 dataOffset),
526 changeRecordDataSize - dataOffset,
527 static_cast<size_t>(numberOfChangeEntries),
528 pdrRecordHandles);
529
530 if (rc != PLDM_SUCCESS)
531 {
532 return rc;
533 }
534 }
535
536 changeRecordData +=
537 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
538 changeRecordDataSize -=
539 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
540 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500541 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500542 if (hostPDRHandler)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500543 {
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500544 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500545 }
546
547 return PLDM_SUCCESS;
548}
549
550int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
551 size_t changeEntryDataSize,
552 size_t numberOfChangeEntries,
553 PDRRecordHandles& pdrRecordHandles)
554{
555 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
556 {
557 return PLDM_ERROR_INVALID_DATA;
558 }
559 for (size_t i = 0; i < numberOfChangeEntries; i++)
560 {
561 pdrRecordHandles.push_back(changeEntryData[i]);
562 }
563 return PLDM_SUCCESS;
564}
565
George Liueccb0c52020-01-14 11:09:56 +0800566Response Handler::setNumericEffecterValue(const pldm_msg* request,
567 size_t payloadLength)
568{
569 Response response(sizeof(pldm_msg_hdr) +
570 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
571 uint16_t effecterId{};
572 uint8_t effecterDataSize{};
573 uint8_t effecterValue[4] = {};
574
575 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
576 sizeof(union_effecter_data_size)) ||
577 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
578 {
579 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
580 }
581
582 int rc = decode_set_numeric_effecter_value_req(
583 request, payloadLength, &effecterId, &effecterDataSize,
584 reinterpret_cast<uint8_t*>(&effecterValue));
585
586 if (rc == PLDM_SUCCESS)
587 {
588 const pldm::utils::DBusHandler dBusIntf;
589 rc = platform_numeric_effecter::setNumericEffecterValueHandler<
590 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
591 effecterDataSize, effecterValue,
592 sizeof(effecterValue));
593 }
594
595 return ccOnlyResponse(request, rc);
596}
597
Sampa Misra12afe112020-05-25 11:40:44 -0500598void Handler::generateTerminusLocatorPDR(Repo& repo)
599{
600 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
601
602 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
603
604 pdr->hdr.record_handle = 0;
605 pdr->hdr.version = 1;
606 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
607 pdr->hdr.record_change_num = 0;
608 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
609 pdr->terminus_handle = BmcPldmTerminusHandle;
610 pdr->validity = PLDM_TL_PDR_VALID;
611 pdr->tid = BmcTerminusId;
612 pdr->container_id = 0x0;
613 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
614 pdr->terminus_locator_value_size =
615 sizeof(pldm_terminus_locator_type_mctp_eid);
616 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
617 pdr->terminus_locator_value);
618 locatorValue->eid = BmcMctpEid;
619
620 PdrEntry pdrEntry{};
621 pdrEntry.data = pdrBuffer.data();
622 pdrEntry.size = pdrBuffer.size();
623 repo.addRecord(pdrEntry);
624}
George Liu362c18d2020-05-14 09:46:36 +0800625
626Response Handler::getStateSensorReadings(const pldm_msg* request,
627 size_t payloadLength)
628{
629 uint16_t sensorId{};
630 bitfield8_t sensorRearm{};
631 uint8_t reserved{};
632
633 if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES)
634 {
635 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
636 }
637
638 int rc = decode_get_state_sensor_readings_req(
639 request, payloadLength, &sensorId, &sensorRearm, &reserved);
640
641 if (rc != PLDM_SUCCESS)
642 {
643 return ccOnlyResponse(request, rc);
644 }
645
646 // 0x01 to 0x08
647 uint8_t sensorRearmCout = getBitfieldCount(sensorRearm);
648 std::vector<get_sensor_state_field> stateField(sensorRearmCout);
649 uint8_t comSensorCnt{};
650 const pldm::utils::DBusHandler dBusIntf;
651 rc = platform_state_sensor::getStateSensorReadingsHandler<
652 pldm::utils::DBusHandler, Handler>(
653 dBusIntf, *this, sensorId, sensorRearmCout, comSensorCnt, stateField);
654
655 if (rc != PLDM_SUCCESS)
656 {
657 return ccOnlyResponse(request, rc);
658 }
659
660 Response response(sizeof(pldm_msg_hdr) +
661 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
662 sizeof(get_sensor_state_field) * comSensorCnt);
663 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
664 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
665 comSensorCnt, stateField.data(),
666 responsePtr);
667 if (rc != PLDM_SUCCESS)
668 {
669 return ccOnlyResponse(request, rc);
670 }
671
672 return response;
673}
674
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600675} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530676} // namespace responder
677} // namespace pldm