1 
2 #include "platform.hpp"
3 
4 #include "libpldm/entity.h"
5 #include "libpldm/state_set.h"
6 
7 #include "common/types.hpp"
8 #include "common/utils.hpp"
9 #include "event_parser.hpp"
10 #include "pdr.hpp"
11 #include "pdr_numeric_effecter.hpp"
12 #include "pdr_state_effecter.hpp"
13 #include "pdr_state_sensor.hpp"
14 #include "pdr_utils.hpp"
15 #include "platform_numeric_effecter.hpp"
16 #include "platform_state_effecter.hpp"
17 #include "platform_state_sensor.hpp"
18 
19 namespace pldm
20 {
21 namespace responder
22 {
23 namespace platform
24 {
25 
26 using InternalFailure =
27     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
28 
29 static const Json empty{};
30 
31 void Handler::addDbusObjMaps(
32     uint16_t id,
33     std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
34     TypeId typeId)
35 {
36     if (typeId == TypeId::PLDM_SENSOR_ID)
37     {
38         sensorDbusObjMaps.emplace(id, dbusObj);
39     }
40     else
41     {
42         effecterDbusObjMaps.emplace(id, dbusObj);
43     }
44 }
45 
46 const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
47     Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
48 {
49     if (typeId == TypeId::PLDM_SENSOR_ID)
50     {
51         return sensorDbusObjMaps.at(id);
52     }
53     else
54     {
55         return effecterDbusObjMaps.at(id);
56     }
57 }
58 
59 void Handler::generate(const pldm::utils::DBusHandler& dBusIntf,
60                        const std::string& dir, Repo& repo)
61 {
62     if (!fs::exists(dir))
63     {
64         return;
65     }
66 
67     // 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.
71 
72     const std::map<Type, generatePDR> generateHandlers = {
73         {PLDM_STATE_EFFECTER_PDR,
74          [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);
79          }},
80         {PLDM_NUMERIC_EFFECTER_PDR,
81          [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);
86          }},
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);
92          }}};
93 
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             {
102                 auto effecterPDRs = json.value("effecterPDRs", empty);
103                 for (const auto& effecter : effecterPDRs)
104                 {
105                     pdrType = effecter.value("pdrType", 0);
106                     generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
107                 }
108 
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                 }
115             }
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 }
139 
140 Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
141 {
142     // 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 
149     if (!pdrCreated)
150     {
151         generateTerminusLocatorPDR(pdrRepo);
152         generate(*dBusIntf, pdrJsonsDir, pdrRepo);
153         if (oemPlatformHandler != nullptr)
154         {
155             oemPlatformHandler->buildOEMPDR(pdrRepo);
156         }
157 
158         pdrCreated = true;
159 
160         if (dbusToPLDMEventHandler)
161         {
162             dbusToPLDMEventHandler->listenSensorEvent(pdrRepo,
163                                                       sensorDbusObjMaps);
164         }
165     }
166 
167     Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
168     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
169 
170     if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
171     {
172         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
173     }
174 
175     uint32_t recordHandle{};
176     uint32_t dataTransferHandle{};
177     uint8_t transferOpFlag{};
178     uint16_t reqSizeBytes{};
179     uint16_t recordChangeNum{};
180 
181     auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
182                                  &dataTransferHandle, &transferOpFlag,
183                                  &reqSizeBytes, &recordChangeNum);
184     if (rc != PLDM_SUCCESS)
185     {
186         return CmdHandler::ccOnlyResponse(request, rc);
187     }
188 
189     uint16_t respSizeBytes{};
190     uint8_t* recordData = nullptr;
191     try
192     {
193         pdr_utils::PdrEntry e;
194         auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
195         if (record == NULL)
196         {
197             return CmdHandler::ccOnlyResponse(
198                 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
199         }
200 
201         if (reqSizeBytes)
202         {
203             respSizeBytes = e.size;
204             if (respSizeBytes > reqSizeBytes)
205             {
206                 respSizeBytes = reqSizeBytes;
207             }
208             recordData = e.data;
209         }
210         response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
211                             respSizeBytes,
212                         0);
213         responsePtr = reinterpret_cast<pldm_msg*>(response.data());
214         rc = encode_get_pdr_resp(
215             request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
216             0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
217         if (rc != PLDM_SUCCESS)
218         {
219             return ccOnlyResponse(request, rc);
220         }
221     }
222     catch (const std::exception& e)
223     {
224         std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
225                   << " ERROR=" << e.what() << "\n";
226         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
227     }
228     return response;
229 }
230 
231 Response Handler::setStateEffecterStates(const pldm_msg* request,
232                                          size_t payloadLength)
233 {
234     Response response(
235         sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
236     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
237     uint16_t effecterId;
238     uint8_t compEffecterCnt;
239     constexpr auto maxCompositeEffecterCnt = 8;
240     std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
241                                                      {0, 0});
242 
243     if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
244         (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
245                              sizeof(set_effecter_state_field)))
246     {
247         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
248     }
249 
250     int rc = decode_set_state_effecter_states_req(request, payloadLength,
251                                                   &effecterId, &compEffecterCnt,
252                                                   stateField.data());
253 
254     if (rc != PLDM_SUCCESS)
255     {
256         return CmdHandler::ccOnlyResponse(request, rc);
257     }
258 
259     stateField.resize(compEffecterCnt);
260     const pldm::utils::DBusHandler dBusIntf;
261     uint16_t entityType{};
262     uint16_t entityInstance{};
263     uint16_t stateSetId{};
264 
265     if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
266                            entityInstance, stateSetId) &&
267         oemPlatformHandler != nullptr)
268     {
269         rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
270             entityType, entityInstance, stateSetId, compEffecterCnt, stateField,
271             effecterId);
272     }
273     else
274     {
275         rc = platform_state_effecter::setStateEffecterStatesHandler<
276             pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
277                                                stateField);
278     }
279     if (rc != PLDM_SUCCESS)
280     {
281         return CmdHandler::ccOnlyResponse(request, rc);
282     }
283 
284     rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
285                                                responsePtr);
286     if (rc != PLDM_SUCCESS)
287     {
288         return ccOnlyResponse(request, rc);
289     }
290 
291     return response;
292 }
293 
294 Response Handler::platformEventMessage(const pldm_msg* request,
295                                        size_t payloadLength)
296 {
297     uint8_t formatVersion{};
298     uint8_t tid{};
299     uint8_t eventClass{};
300     size_t offset{};
301 
302     auto rc = decode_platform_event_message_req(
303         request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
304     if (rc != PLDM_SUCCESS)
305     {
306         return CmdHandler::ccOnlyResponse(request, rc);
307     }
308 
309     try
310     {
311         const auto& handlers = eventHandlers.at(eventClass);
312         for (const auto& handler : handlers)
313         {
314             auto rc =
315                 handler(request, payloadLength, formatVersion, tid, offset);
316             if (rc != PLDM_SUCCESS)
317             {
318                 return CmdHandler::ccOnlyResponse(request, rc);
319             }
320         }
321     }
322     catch (const std::out_of_range& e)
323     {
324         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
325     }
326 
327     Response response(
328         sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
329     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
330 
331     rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
332                                             PLDM_EVENT_NO_LOGGING, responsePtr);
333     if (rc != PLDM_SUCCESS)
334     {
335         return ccOnlyResponse(request, rc);
336     }
337 
338     return response;
339 }
340 
341 int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
342                          uint8_t /*formatVersion*/, uint8_t tid,
343                          size_t eventDataOffset)
344 {
345     uint16_t sensorId{};
346     uint8_t eventClass{};
347     size_t eventClassDataOffset{};
348     auto eventData =
349         reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
350     auto eventDataSize = payloadLength - eventDataOffset;
351 
352     auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
353                                        &eventClass, &eventClassDataOffset);
354     if (rc != PLDM_SUCCESS)
355     {
356         return rc;
357     }
358 
359     auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
360                           eventDataOffset + eventClassDataOffset;
361     auto eventClassDataSize =
362         payloadLength - eventDataOffset - eventClassDataOffset;
363 
364     if (eventClass == PLDM_STATE_SENSOR_STATE)
365     {
366         uint8_t sensorOffset{};
367         uint8_t eventState{};
368         uint8_t previousEventState{};
369 
370         rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
371                                       &sensorOffset, &eventState,
372                                       &previousEventState);
373         if (rc != PLDM_SUCCESS)
374         {
375             return PLDM_ERROR;
376         }
377 
378         // Emitting state sensor event signal
379         emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
380                                    previousEventState);
381 
382         // If there are no HOST PDR's, there is no further action
383         if (hostPDRHandler == NULL)
384         {
385             return PLDM_SUCCESS;
386         }
387 
388         // Handle PLDM events for which PDR is available
389         SensorEntry sensorEntry{tid, sensorId};
390 
391         pldm::pdr::EntityInfo entityInfo{};
392         pldm::pdr::CompositeSensorStates compositeSensorStates{};
393 
394         try
395         {
396             std::tie(entityInfo, compositeSensorStates) =
397                 hostPDRHandler->lookupSensorInfo(sensorEntry);
398         }
399         catch (const std::out_of_range& e)
400         {
401             // If there is no mapping for tid, sensorId combination, try
402             // PLDM_TID_RESERVED, sensorId for terminus that is yet to
403             // implement TL PDR.
404             try
405             {
406                 sensorEntry.terminusID = PLDM_TID_RESERVED;
407                 std::tie(entityInfo, compositeSensorStates) =
408                     hostPDRHandler->lookupSensorInfo(sensorEntry);
409             }
410             // If there is no mapping for events return PLDM_SUCCESS
411             catch (const std::out_of_range& e)
412             {
413                 return PLDM_SUCCESS;
414             }
415         }
416 
417         if (sensorOffset >= compositeSensorStates.size())
418         {
419             return PLDM_ERROR_INVALID_DATA;
420         }
421 
422         const auto& possibleStates = compositeSensorStates[sensorOffset];
423         if (possibleStates.find(eventState) == possibleStates.end())
424         {
425             return PLDM_ERROR_INVALID_DATA;
426         }
427 
428         const auto& [containerId, entityType, entityInstance] = entityInfo;
429         events::StateSensorEntry stateSensorEntry{containerId, entityType,
430                                                   entityInstance, sensorOffset};
431         return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
432                                                       eventState);
433     }
434     else
435     {
436         return PLDM_ERROR_INVALID_DATA;
437     }
438 
439     return PLDM_SUCCESS;
440 }
441 
442 int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
443                                        size_t payloadLength,
444                                        uint8_t /*formatVersion*/,
445                                        uint8_t /*tid*/, size_t eventDataOffset)
446 {
447     uint8_t eventDataFormat{};
448     uint8_t numberOfChangeRecords{};
449     size_t dataOffset{};
450 
451     auto eventData =
452         reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
453     auto eventDataSize = payloadLength - eventDataOffset;
454 
455     auto rc = decode_pldm_pdr_repository_chg_event_data(
456         eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
457         &dataOffset);
458     if (rc != PLDM_SUCCESS)
459     {
460         return rc;
461     }
462 
463     PDRRecordHandles pdrRecordHandles;
464 
465     if (eventDataFormat == FORMAT_IS_PDR_TYPES)
466     {
467         return PLDM_ERROR_INVALID_DATA;
468     }
469 
470     if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
471     {
472         uint8_t eventDataOperation{};
473         uint8_t numberOfChangeEntries{};
474 
475         auto changeRecordData = eventData + dataOffset;
476         auto changeRecordDataSize = eventDataSize - dataOffset;
477 
478         while (changeRecordDataSize)
479         {
480             rc = decode_pldm_pdr_repository_change_record_data(
481                 changeRecordData, changeRecordDataSize, &eventDataOperation,
482                 &numberOfChangeEntries, &dataOffset);
483 
484             if (rc != PLDM_SUCCESS)
485             {
486                 return rc;
487             }
488 
489             if (eventDataOperation == PLDM_RECORDS_ADDED)
490             {
491                 rc = getPDRRecordHandles(
492                     reinterpret_cast<const ChangeEntry*>(changeRecordData +
493                                                          dataOffset),
494                     changeRecordDataSize - dataOffset,
495                     static_cast<size_t>(numberOfChangeEntries),
496                     pdrRecordHandles);
497 
498                 if (rc != PLDM_SUCCESS)
499                 {
500                     return rc;
501                 }
502             }
503 
504             changeRecordData +=
505                 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
506             changeRecordDataSize -=
507                 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
508         }
509     }
510     if (hostPDRHandler)
511     {
512         hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
513     }
514 
515     return PLDM_SUCCESS;
516 }
517 
518 int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
519                                  size_t changeEntryDataSize,
520                                  size_t numberOfChangeEntries,
521                                  PDRRecordHandles& pdrRecordHandles)
522 {
523     if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
524     {
525         return PLDM_ERROR_INVALID_DATA;
526     }
527     for (size_t i = 0; i < numberOfChangeEntries; i++)
528     {
529         pdrRecordHandles.push_back(changeEntryData[i]);
530     }
531     return PLDM_SUCCESS;
532 }
533 
534 Response Handler::setNumericEffecterValue(const pldm_msg* request,
535                                           size_t payloadLength)
536 {
537     Response response(sizeof(pldm_msg_hdr) +
538                       PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
539     uint16_t effecterId{};
540     uint8_t effecterDataSize{};
541     uint8_t effecterValue[4] = {};
542 
543     if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
544                              sizeof(union_effecter_data_size)) ||
545         (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
546     {
547         return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
548     }
549 
550     int rc = decode_set_numeric_effecter_value_req(
551         request, payloadLength, &effecterId, &effecterDataSize,
552         reinterpret_cast<uint8_t*>(&effecterValue));
553 
554     if (rc == PLDM_SUCCESS)
555     {
556         const pldm::utils::DBusHandler dBusIntf;
557         rc = platform_numeric_effecter::setNumericEffecterValueHandler<
558             pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
559                                                effecterDataSize, effecterValue,
560                                                sizeof(effecterValue));
561     }
562 
563     return ccOnlyResponse(request, rc);
564 }
565 
566 void Handler::generateTerminusLocatorPDR(Repo& repo)
567 {
568     std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
569 
570     auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
571 
572     pdr->hdr.record_handle = 0;
573     pdr->hdr.version = 1;
574     pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
575     pdr->hdr.record_change_num = 0;
576     pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
577     pdr->terminus_handle = BmcPldmTerminusHandle;
578     pdr->validity = PLDM_TL_PDR_VALID;
579     pdr->tid = BmcTerminusId;
580     pdr->container_id = 0x0;
581     pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
582     pdr->terminus_locator_value_size =
583         sizeof(pldm_terminus_locator_type_mctp_eid);
584     auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
585         pdr->terminus_locator_value);
586     locatorValue->eid = BmcMctpEid;
587 
588     PdrEntry pdrEntry{};
589     pdrEntry.data = pdrBuffer.data();
590     pdrEntry.size = pdrBuffer.size();
591     repo.addRecord(pdrEntry);
592 }
593 
594 Response Handler::getStateSensorReadings(const pldm_msg* request,
595                                          size_t payloadLength)
596 {
597     uint16_t sensorId{};
598     bitfield8_t sensorRearm{};
599     uint8_t reserved{};
600 
601     if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES)
602     {
603         return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
604     }
605 
606     int rc = decode_get_state_sensor_readings_req(
607         request, payloadLength, &sensorId, &sensorRearm, &reserved);
608 
609     if (rc != PLDM_SUCCESS)
610     {
611         return ccOnlyResponse(request, rc);
612     }
613 
614     // 0x01 to 0x08
615     uint8_t sensorRearmCount = getBitfieldCount(sensorRearm);
616     std::vector<get_sensor_state_field> stateField(sensorRearmCount);
617     uint8_t comSensorCnt{};
618     const pldm::utils::DBusHandler dBusIntf;
619 
620     uint16_t entityType{};
621     uint16_t entityInstance{};
622     uint16_t stateSetId{};
623 
624     if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
625                          entityType, entityInstance, stateSetId) &&
626         oemPlatformHandler != nullptr)
627     {
628         rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
629             entityType, entityInstance, stateSetId, comSensorCnt, stateField);
630     }
631     else
632     {
633         rc = platform_state_sensor::getStateSensorReadingsHandler<
634             pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId,
635                                                sensorRearmCount, comSensorCnt,
636                                                stateField);
637     }
638 
639     if (rc != PLDM_SUCCESS)
640     {
641         return ccOnlyResponse(request, rc);
642     }
643 
644     Response response(sizeof(pldm_msg_hdr) +
645                       PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
646                       sizeof(get_sensor_state_field) * comSensorCnt);
647     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
648     rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
649                                                comSensorCnt, stateField.data(),
650                                                responsePtr);
651     if (rc != PLDM_SUCCESS)
652     {
653         return ccOnlyResponse(request, rc);
654     }
655 
656     return response;
657 }
658 
659 bool isOemStateSensor(Handler& handler, uint16_t sensorId,
660                       uint8_t sensorRearmCount, uint8_t& compSensorCnt,
661                       uint16_t& entityType, uint16_t& entityInstance,
662                       uint16_t& stateSetId)
663 {
664     pldm_state_sensor_pdr* pdr = nullptr;
665 
666     std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
667         pldm_pdr_init(), pldm_pdr_destroy);
668     Repo stateSensorPDRs(stateSensorPdrRepo.get());
669     getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
670     if (stateSensorPDRs.empty())
671     {
672         std::cerr << "Failed to get record by PDR type\n";
673         return false;
674     }
675 
676     PdrEntry pdrEntry{};
677     auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
678     while (pdrRecord)
679     {
680         pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
681         assert(pdr != NULL);
682         if (pdr->sensor_id != sensorId)
683         {
684             pdr = nullptr;
685             pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
686             continue;
687         }
688         auto tmpEntityType = pdr->entity_type;
689         auto tmpEntityInstance = pdr->entity_instance;
690         auto tmpCompSensorCnt = pdr->composite_sensor_count;
691         auto tmpPossibleStates =
692             reinterpret_cast<state_sensor_possible_states*>(
693                 pdr->possible_states);
694         auto tmpStateSetId = tmpPossibleStates->state_set_id;
695 
696         if (sensorRearmCount > tmpCompSensorCnt)
697         {
698             std::cerr << "The requester sent wrong sensorRearm"
699                       << " count for the sensor, SENSOR_ID=" << sensorId
700                       << "SENSOR_REARM_COUNT=" << (uint16_t)sensorRearmCount
701                       << "\n";
702             break;
703         }
704 
705         if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
706              tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
707             (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
708              tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
709         {
710             entityType = tmpEntityType;
711             entityInstance = tmpEntityInstance;
712             stateSetId = tmpStateSetId;
713             compSensorCnt = tmpCompSensorCnt;
714             return true;
715         }
716         else
717         {
718             return false;
719         }
720     }
721     return false;
722 }
723 
724 bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
725                         uint8_t compEffecterCnt, uint16_t& entityType,
726                         uint16_t& entityInstance, uint16_t& stateSetId)
727 {
728     pldm_state_effecter_pdr* pdr = nullptr;
729 
730     std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
731         pldm_pdr_init(), pldm_pdr_destroy);
732     Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
733     getRepoByType(handler.getRepo(), stateEffecterPDRs,
734                   PLDM_STATE_EFFECTER_PDR);
735     if (stateEffecterPDRs.empty())
736     {
737         std::cerr << "Failed to get record by PDR type\n";
738         return false;
739     }
740 
741     PdrEntry pdrEntry{};
742     auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
743     while (pdrRecord)
744     {
745         pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
746         assert(pdr != NULL);
747         if (pdr->effecter_id != effecterId)
748         {
749             pdr = nullptr;
750             pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
751             continue;
752         }
753 
754         auto tmpEntityType = pdr->entity_type;
755         auto tmpEntityInstance = pdr->entity_instance;
756         auto tmpPossibleStates =
757             reinterpret_cast<state_effecter_possible_states*>(
758                 pdr->possible_states);
759         auto tmpStateSetId = tmpPossibleStates->state_set_id;
760 
761         if (compEffecterCnt > pdr->composite_effecter_count)
762         {
763             std::cerr << "The requester sent wrong composite effecter"
764                       << " count for the effecter, EFFECTER_ID=" << effecterId
765                       << "COMP_EFF_CNT=" << (uint16_t)compEffecterCnt << "\n";
766             return false;
767         }
768 
769         if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
770              tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
771             (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
772              tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
773         {
774             entityType = tmpEntityType;
775             entityInstance = tmpEntityInstance;
776             stateSetId = tmpStateSetId;
777             return true;
778         }
779         else
780         {
781             return false;
782         }
783     }
784     return false;
785 }
786 
787 } // namespace platform
788 } // namespace responder
789 } // namespace pldm
790