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         pdrCreated = true;
154     }
155 
156     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     {
161         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
162     }
163 
164     uint32_t recordHandle{};
165     uint32_t dataTransferHandle{};
166     uint8_t transferOpFlag{};
167     uint16_t reqSizeBytes{};
168     uint16_t recordChangeNum{};
169 
170     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     }
177 
178     uint16_t respSizeBytes{};
179     uint8_t* recordData = nullptr;
180     try
181     {
182         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 
190         if (reqSizeBytes)
191         {
192             respSizeBytes = e.size;
193             if (respSizeBytes > reqSizeBytes)
194             {
195                 respSizeBytes = reqSizeBytes;
196             }
197             recordData = e.data;
198         }
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());
203         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);
206         if (rc != PLDM_SUCCESS)
207         {
208             return ccOnlyResponse(request, rc);
209         }
210     }
211     catch (const std::exception& e)
212     {
213         std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
214                   << " ERROR=" << e.what() << "\n";
215         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
216     }
217     return response;
218 }
219 
220 Response Handler::setStateEffecterStates(const pldm_msg* request,
221                                          size_t payloadLength)
222 {
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     {
236         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
237     }
238 
239     int rc = decode_set_state_effecter_states_req(request, payloadLength,
240                                                   &effecterId, &compEffecterCnt,
241                                                   stateField.data());
242 
243     if (rc != PLDM_SUCCESS)
244     {
245         return CmdHandler::ccOnlyResponse(request, rc);
246     }
247 
248     stateField.resize(compEffecterCnt);
249     const pldm::utils::DBusHandler dBusIntf;
250     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     }
268     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 
280     return response;
281 }
282 
283 Response 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 
330 int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
331                          uint8_t /*formatVersion*/, uint8_t tid,
332                          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 
348     auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
349                           eventDataOffset + eventClassDataOffset;
350     auto eventClassDataSize =
351         payloadLength - eventDataOffset - eventClassDataOffset;
352 
353     if (eventClass == PLDM_STATE_SENSOR_STATE)
354     {
355         uint8_t sensorOffset{};
356         uint8_t eventState{};
357         uint8_t previousEventState{};
358 
359         rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
360                                       &sensorOffset, &eventState,
361                                       &previousEventState);
362         if (rc != PLDM_SUCCESS)
363         {
364             return PLDM_ERROR;
365         }
366 
367         // Emitting state sensor event signal
368         emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
369                                    previousEventState);
370 
371         // 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};
379 
380         pldm::pdr::EntityInfo entityInfo{};
381         pldm::pdr::CompositeSensorStates compositeSensorStates{};
382 
383         try
384         {
385             std::tie(entityInfo, compositeSensorStates) =
386                 hostPDRHandler->lookupSensorInfo(sensorEntry);
387         }
388         catch (const std::out_of_range& e)
389         {
390             // 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             }
404         }
405 
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};
420         return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
421                                                       eventState);
422     }
423     else
424     {
425         return PLDM_ERROR_INVALID_DATA;
426     }
427 
428     return PLDM_SUCCESS;
429 }
430 
431 int 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;
453 
454     if (eventDataFormat == FORMAT_IS_PDR_TYPES)
455     {
456         return PLDM_ERROR_INVALID_DATA;
457     }
458 
459     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         }
498     }
499     if (hostPDRHandler)
500     {
501         hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
502     }
503 
504     return PLDM_SUCCESS;
505 }
506 
507 int 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 
523 Response 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 
555 void 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 }
582 
583 Response 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
604     uint8_t sensorRearmCount = getBitfieldCount(sensorRearm);
605     std::vector<get_sensor_state_field> stateField(sensorRearmCount);
606     uint8_t comSensorCnt{};
607     const pldm::utils::DBusHandler dBusIntf;
608 
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     }
627 
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 
648 bool 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 
713 bool 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 
776 } // namespace platform
777 } // namespace responder
778 } // namespace pldm
779