1 
2 #include "platform.hpp"
3 
4 #include "common/utils.hpp"
5 #include "event_parser.hpp"
6 #include "pdr.hpp"
7 #include "pdr_numeric_effecter.hpp"
8 #include "pdr_state_effecter.hpp"
9 #include "pdr_state_sensor.hpp"
10 #include "pdr_utils.hpp"
11 #include "platform_numeric_effecter.hpp"
12 #include "platform_state_effecter.hpp"
13 #include "platform_state_sensor.hpp"
14 
15 namespace pldm
16 {
17 namespace responder
18 {
19 namespace platform
20 {
21 
22 using InternalFailure =
23     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
24 
25 static const Json empty{};
26 
27 using EventEntryMap = std::map<EventEntry, DBusInfo>;
28 
29 const 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)
34         {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0",
35          "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)
41         {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0",
42          "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)
48         {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0",
49          "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)
55         {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0",
56          "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
57     }};
58 
59 void Handler::addDbusObjMaps(
60     uint16_t id,
61     std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
62     TypeId typeId)
63 {
64     if (typeId == TypeId::PLDM_SENSOR_ID)
65     {
66         sensorDbusObjMaps.emplace(id, dbusObj);
67     }
68     else
69     {
70         effecterDbusObjMaps.emplace(id, dbusObj);
71     }
72 }
73 
74 const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
75     Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
76 {
77     if (typeId == TypeId::PLDM_SENSOR_ID)
78     {
79         return sensorDbusObjMaps.at(id);
80     }
81     else
82     {
83         return effecterDbusObjMaps.at(id);
84     }
85 }
86 
87 void Handler::generate(const pldm::utils::DBusHandler& dBusIntf,
88                        const std::string& dir, Repo& repo)
89 {
90     if (!fs::exists(dir))
91     {
92         return;
93     }
94 
95     // 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.
99 
100     const std::map<Type, generatePDR> generateHandlers = {
101         {PLDM_STATE_EFFECTER_PDR,
102          [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);
107          }},
108         {PLDM_NUMERIC_EFFECTER_PDR,
109          [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);
114          }},
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);
120          }}};
121 
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             {
130                 auto effecterPDRs = json.value("effecterPDRs", empty);
131                 for (const auto& effecter : effecterPDRs)
132                 {
133                     pdrType = effecter.value("pdrType", 0);
134                     generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
135                 }
136 
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                 }
143             }
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 }
167 
168 Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
169 {
170     if (!pdrCreated)
171     {
172         generateTerminusLocatorPDR(pdrRepo);
173         generate(*dBusIntf, pdrJsonsDir, pdrRepo);
174         pdrCreated = true;
175     }
176 
177     // Build FRU table if not built, since entity association PDR's are built
178     // when the FRU table is constructed.
179     if (fruHandler)
180     {
181         fruHandler->buildFRUTable();
182     }
183 
184     Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
185     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
186 
187     if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
188     {
189         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
190     }
191 
192     uint32_t recordHandle{};
193     uint32_t dataTransferHandle{};
194     uint8_t transferOpFlag{};
195     uint16_t reqSizeBytes{};
196     uint16_t recordChangeNum{};
197 
198     auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
199                                  &dataTransferHandle, &transferOpFlag,
200                                  &reqSizeBytes, &recordChangeNum);
201     if (rc != PLDM_SUCCESS)
202     {
203         return CmdHandler::ccOnlyResponse(request, rc);
204     }
205 
206     uint16_t respSizeBytes{};
207     uint8_t* recordData = nullptr;
208     try
209     {
210         pdr_utils::PdrEntry e;
211         auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
212         if (record == NULL)
213         {
214             return CmdHandler::ccOnlyResponse(
215                 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
216         }
217 
218         if (reqSizeBytes)
219         {
220             respSizeBytes = e.size;
221             if (respSizeBytes > reqSizeBytes)
222             {
223                 respSizeBytes = reqSizeBytes;
224             }
225             recordData = e.data;
226         }
227         response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
228                             respSizeBytes,
229                         0);
230         responsePtr = reinterpret_cast<pldm_msg*>(response.data());
231         rc = encode_get_pdr_resp(
232             request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
233             0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
234         if (rc != PLDM_SUCCESS)
235         {
236             return ccOnlyResponse(request, rc);
237         }
238     }
239     catch (const std::exception& e)
240     {
241         std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
242                   << " ERROR=" << e.what() << "\n";
243         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
244     }
245     return response;
246 }
247 
248 Response Handler::setStateEffecterStates(const pldm_msg* request,
249                                          size_t payloadLength)
250 {
251     Response response(
252         sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
253     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
254     uint16_t effecterId;
255     uint8_t compEffecterCnt;
256     constexpr auto maxCompositeEffecterCnt = 8;
257     std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
258                                                      {0, 0});
259 
260     if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
261         (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
262                              sizeof(set_effecter_state_field)))
263     {
264         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
265     }
266 
267     int rc = decode_set_state_effecter_states_req(request, payloadLength,
268                                                   &effecterId, &compEffecterCnt,
269                                                   stateField.data());
270 
271     if (rc != PLDM_SUCCESS)
272     {
273         return CmdHandler::ccOnlyResponse(request, rc);
274     }
275 
276     stateField.resize(compEffecterCnt);
277     const pldm::utils::DBusHandler dBusIntf;
278     rc = platform_state_effecter::setStateEffecterStatesHandler<
279         pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
280                                            stateField);
281     if (rc != PLDM_SUCCESS)
282     {
283         return CmdHandler::ccOnlyResponse(request, rc);
284     }
285 
286     rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
287                                                responsePtr);
288     if (rc != PLDM_SUCCESS)
289     {
290         return ccOnlyResponse(request, rc);
291     }
292 
293     return response;
294 }
295 
296 Response Handler::platformEventMessage(const pldm_msg* request,
297                                        size_t payloadLength)
298 {
299     uint8_t formatVersion{};
300     uint8_t tid{};
301     uint8_t eventClass{};
302     size_t offset{};
303 
304     auto rc = decode_platform_event_message_req(
305         request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
306     if (rc != PLDM_SUCCESS)
307     {
308         return CmdHandler::ccOnlyResponse(request, rc);
309     }
310 
311     try
312     {
313         const auto& handlers = eventHandlers.at(eventClass);
314         for (const auto& handler : handlers)
315         {
316             auto rc =
317                 handler(request, payloadLength, formatVersion, tid, offset);
318             if (rc != PLDM_SUCCESS)
319             {
320                 return CmdHandler::ccOnlyResponse(request, rc);
321             }
322         }
323     }
324     catch (const std::out_of_range& e)
325     {
326         return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
327     }
328 
329     Response response(
330         sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
331     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
332 
333     rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
334                                             PLDM_EVENT_NO_LOGGING, responsePtr);
335     if (rc != PLDM_SUCCESS)
336     {
337         return ccOnlyResponse(request, rc);
338     }
339 
340     return response;
341 }
342 
343 int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
344                          uint8_t /*formatVersion*/, uint8_t tid,
345                          size_t eventDataOffset)
346 {
347     uint16_t sensorId{};
348     uint8_t eventClass{};
349     size_t eventClassDataOffset{};
350     auto eventData =
351         reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
352     auto eventDataSize = payloadLength - eventDataOffset;
353 
354     auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
355                                        &eventClass, &eventClassDataOffset);
356     if (rc != PLDM_SUCCESS)
357     {
358         return rc;
359     }
360 
361     auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
362                           eventDataOffset + eventClassDataOffset;
363     auto eventClassDataSize =
364         payloadLength - eventDataOffset - eventClassDataOffset;
365 
366     if (eventClass == PLDM_STATE_SENSOR_STATE)
367     {
368         uint8_t sensorOffset{};
369         uint8_t eventState{};
370         uint8_t previousEventState{};
371 
372         rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
373                                       &sensorOffset, &eventState,
374                                       &previousEventState);
375         if (rc != PLDM_SUCCESS)
376         {
377             return PLDM_ERROR;
378         }
379 
380         // Emitting state sensor event signal
381         emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
382                                    previousEventState);
383 
384         // Handle PLDM events for which PDR is not available, setSensorEventData
385         // will return PLDM_ERROR_INVALID_DATA if the sensorID is not found in
386         // the hardcoded sensor list.
387         rc = setSensorEventData(sensorId, sensorOffset, eventState);
388         if (rc != PLDM_ERROR_INVALID_DATA)
389         {
390             return rc;
391         }
392 
393         // If there are no HOST PDR's, there is no further action
394         if (hostPDRHandler == NULL)
395         {
396             return PLDM_SUCCESS;
397         }
398 
399         // Handle PLDM events for which PDR is available
400         SensorEntry sensorEntry{tid, sensorId};
401         try
402         {
403             const auto& [entityInfo, compositeSensorStates] =
404                 hostPDRHandler->lookupSensorInfo(sensorEntry);
405             if (sensorOffset >= compositeSensorStates.size())
406             {
407                 return PLDM_ERROR_INVALID_DATA;
408             }
409 
410             const auto& possibleStates = compositeSensorStates[sensorOffset];
411             if (possibleStates.find(eventState) == possibleStates.end())
412             {
413                 return PLDM_ERROR_INVALID_DATA;
414             }
415 
416             const auto& [containerId, entityType, entityInstance] = entityInfo;
417             events::StateSensorEntry stateSensorEntry{
418                 containerId, entityType, entityInstance, sensorOffset};
419             return stateSensorHandler.eventAction(stateSensorEntry, eventState);
420         }
421         // If there is no mapping for events return PLDM_SUCCESS
422         catch (const std::out_of_range& e)
423         {
424             return PLDM_SUCCESS;
425         }
426     }
427     else
428     {
429         return PLDM_ERROR_INVALID_DATA;
430     }
431 
432     return PLDM_SUCCESS;
433 }
434 
435 int Handler::setSensorEventData(uint16_t sensorId, uint8_t sensorOffset,
436                                 uint8_t eventState)
437 {
438     EventEntry eventEntry = ((static_cast<uint32_t>(eventState)) << 24) +
439                             ((static_cast<uint32_t>(sensorOffset)) << 16) +
440                             sensorId;
441     auto iter = eventEntryMap.find(eventEntry);
442     if (iter == eventEntryMap.end())
443     {
444         return PLDM_ERROR_INVALID_DATA;
445     }
446 
447     const auto& dBusInfo = iter->second;
448     try
449     {
450         pldm::utils::DBusMapping dbusMapping{
451             dBusInfo.dBusValues.objectPath, dBusInfo.dBusValues.interface,
452             dBusInfo.dBusValues.propertyName, dBusInfo.dBusValues.propertyType};
453         pldm::utils::DBusHandler().setDbusProperty(dbusMapping,
454                                                    dBusInfo.dBusPropertyValue);
455     }
456     catch (std::exception& e)
457     {
458         std::cerr
459             << "Error Setting dbus property,SensorID=" << eventEntry
460             << "DBusInfo=" << dBusInfo.dBusValues.objectPath
461             << dBusInfo.dBusValues.interface << dBusInfo.dBusValues.propertyName
462             << "ERROR=" << e.what() << "\n";
463         return PLDM_ERROR;
464     }
465     return PLDM_SUCCESS;
466 }
467 
468 int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
469                                        size_t payloadLength,
470                                        uint8_t /*formatVersion*/,
471                                        uint8_t /*tid*/, size_t eventDataOffset)
472 {
473     uint8_t eventDataFormat{};
474     uint8_t numberOfChangeRecords{};
475     size_t dataOffset{};
476 
477     auto eventData =
478         reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
479     auto eventDataSize = payloadLength - eventDataOffset;
480 
481     auto rc = decode_pldm_pdr_repository_chg_event_data(
482         eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
483         &dataOffset);
484     if (rc != PLDM_SUCCESS)
485     {
486         return rc;
487     }
488 
489     PDRRecordHandles pdrRecordHandles;
490 
491     if (eventDataFormat == FORMAT_IS_PDR_TYPES)
492     {
493         return PLDM_ERROR_INVALID_DATA;
494     }
495 
496     if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
497     {
498         uint8_t eventDataOperation{};
499         uint8_t numberOfChangeEntries{};
500 
501         auto changeRecordData = eventData + dataOffset;
502         auto changeRecordDataSize = eventDataSize - dataOffset;
503 
504         while (changeRecordDataSize)
505         {
506             rc = decode_pldm_pdr_repository_change_record_data(
507                 changeRecordData, changeRecordDataSize, &eventDataOperation,
508                 &numberOfChangeEntries, &dataOffset);
509 
510             if (rc != PLDM_SUCCESS)
511             {
512                 return rc;
513             }
514 
515             if (eventDataOperation == PLDM_RECORDS_ADDED)
516             {
517                 rc = getPDRRecordHandles(
518                     reinterpret_cast<const ChangeEntry*>(changeRecordData +
519                                                          dataOffset),
520                     changeRecordDataSize - dataOffset,
521                     static_cast<size_t>(numberOfChangeEntries),
522                     pdrRecordHandles);
523 
524                 if (rc != PLDM_SUCCESS)
525                 {
526                     return rc;
527                 }
528             }
529 
530             changeRecordData +=
531                 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
532             changeRecordDataSize -=
533                 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
534         }
535     }
536     if (hostPDRHandler)
537     {
538         hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
539     }
540 
541     return PLDM_SUCCESS;
542 }
543 
544 int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
545                                  size_t changeEntryDataSize,
546                                  size_t numberOfChangeEntries,
547                                  PDRRecordHandles& pdrRecordHandles)
548 {
549     if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
550     {
551         return PLDM_ERROR_INVALID_DATA;
552     }
553     for (size_t i = 0; i < numberOfChangeEntries; i++)
554     {
555         pdrRecordHandles.push_back(changeEntryData[i]);
556     }
557     return PLDM_SUCCESS;
558 }
559 
560 Response Handler::setNumericEffecterValue(const pldm_msg* request,
561                                           size_t payloadLength)
562 {
563     Response response(sizeof(pldm_msg_hdr) +
564                       PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
565     uint16_t effecterId{};
566     uint8_t effecterDataSize{};
567     uint8_t effecterValue[4] = {};
568 
569     if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
570                              sizeof(union_effecter_data_size)) ||
571         (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
572     {
573         return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
574     }
575 
576     int rc = decode_set_numeric_effecter_value_req(
577         request, payloadLength, &effecterId, &effecterDataSize,
578         reinterpret_cast<uint8_t*>(&effecterValue));
579 
580     if (rc == PLDM_SUCCESS)
581     {
582         const pldm::utils::DBusHandler dBusIntf;
583         rc = platform_numeric_effecter::setNumericEffecterValueHandler<
584             pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
585                                                effecterDataSize, effecterValue,
586                                                sizeof(effecterValue));
587     }
588 
589     return ccOnlyResponse(request, rc);
590 }
591 
592 void Handler::generateTerminusLocatorPDR(Repo& repo)
593 {
594     std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
595 
596     auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
597 
598     pdr->hdr.record_handle = 0;
599     pdr->hdr.version = 1;
600     pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
601     pdr->hdr.record_change_num = 0;
602     pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
603     pdr->terminus_handle = BmcPldmTerminusHandle;
604     pdr->validity = PLDM_TL_PDR_VALID;
605     pdr->tid = BmcTerminusId;
606     pdr->container_id = 0x0;
607     pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
608     pdr->terminus_locator_value_size =
609         sizeof(pldm_terminus_locator_type_mctp_eid);
610     auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
611         pdr->terminus_locator_value);
612     locatorValue->eid = BmcMctpEid;
613 
614     PdrEntry pdrEntry{};
615     pdrEntry.data = pdrBuffer.data();
616     pdrEntry.size = pdrBuffer.size();
617     repo.addRecord(pdrEntry);
618 }
619 
620 Response Handler::getStateSensorReadings(const pldm_msg* request,
621                                          size_t payloadLength)
622 {
623     uint16_t sensorId{};
624     bitfield8_t sensorRearm{};
625     uint8_t reserved{};
626 
627     if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES)
628     {
629         return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
630     }
631 
632     int rc = decode_get_state_sensor_readings_req(
633         request, payloadLength, &sensorId, &sensorRearm, &reserved);
634 
635     if (rc != PLDM_SUCCESS)
636     {
637         return ccOnlyResponse(request, rc);
638     }
639 
640     // 0x01 to 0x08
641     uint8_t sensorRearmCout = getBitfieldCount(sensorRearm);
642     std::vector<get_sensor_state_field> stateField(sensorRearmCout);
643     uint8_t comSensorCnt{};
644     const pldm::utils::DBusHandler dBusIntf;
645     rc = platform_state_sensor::getStateSensorReadingsHandler<
646         pldm::utils::DBusHandler, Handler>(
647         dBusIntf, *this, sensorId, sensorRearmCout, comSensorCnt, stateField);
648 
649     if (rc != PLDM_SUCCESS)
650     {
651         return ccOnlyResponse(request, rc);
652     }
653 
654     Response response(sizeof(pldm_msg_hdr) +
655                       PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
656                       sizeof(get_sensor_state_field) * comSensorCnt);
657     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
658     rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc,
659                                                comSensorCnt, stateField.data(),
660                                                responsePtr);
661     if (rc != PLDM_SUCCESS)
662     {
663         return ccOnlyResponse(request, rc);
664     }
665 
666     return response;
667 }
668 
669 } // namespace platform
670 } // namespace responder
671 } // namespace pldm
672