1 #pragma once
2 
3 #include "common/utils.hpp"
4 #include "event_parser.hpp"
5 #include "fru.hpp"
6 #include "host-bmc/dbus_to_event_handler.hpp"
7 #include "host-bmc/host_pdr_handler.hpp"
8 #include "libpldmresponder/pdr.hpp"
9 #include "libpldmresponder/pdr_utils.hpp"
10 #include "libpldmresponder/platform_config.hpp"
11 #include "oem_handler.hpp"
12 #include "pldmd/handler.hpp"
13 
14 #include <libpldm/pdr.h>
15 #include <libpldm/platform.h>
16 #include <libpldm/states.h>
17 
18 #include <phosphor-logging/lg2.hpp>
19 
20 #include <cstdint>
21 #include <map>
22 
23 PHOSPHOR_LOG2_USING;
24 
25 namespace pldm
26 {
27 namespace responder
28 {
29 namespace platform
30 {
31 using generatePDR = std::function<void(
32     const pldm::utils::DBusHandler& dBusIntf, const pldm::utils::Json& json,
33     pdr_utils::RepoInterface& repo)>;
34 
35 using EffecterId = uint16_t;
36 using DbusObjMaps =
37     std::map<EffecterId,
38              std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>>;
39 using DbusPath = std::string;
40 using EffecterObjs = std::vector<DbusPath>;
41 using EventType = uint8_t;
42 using EventHandler = std::function<int(
43     const pldm_msg* request, size_t payloadLength, uint8_t formatVersion,
44     uint8_t tid, size_t eventDataOffset)>;
45 using EventHandlers = std::vector<EventHandler>;
46 using EventMap = std::map<EventType, EventHandlers>;
47 using AssociatedEntityMap = std::map<DbusPath, pldm_entity>;
48 
49 class Handler : public CmdHandler
50 {
51   public:
Handler(const pldm::utils::DBusHandler * dBusIntf,uint8_t eid,pldm::InstanceIdDb * instanceIdDb,const fs::path & pdrJsonDir,pldm_pdr * repo,HostPDRHandler * hostPDRHandler,pldm::state_sensor::DbusToPLDMEvent * dbusToPLDMEventHandler,fru::Handler * fruHandler,pldm::responder::platform_config::Handler * platformConfigHandler,pldm::requester::Handler<pldm::requester::Request> * handler,sdeventplus::Event & event,bool buildPDRLazily=false,const std::optional<EventMap> & addOnHandlersMap=std::nullopt)52     Handler(const pldm::utils::DBusHandler* dBusIntf, uint8_t eid,
53             pldm::InstanceIdDb* instanceIdDb, const fs::path& pdrJsonDir,
54             pldm_pdr* repo, HostPDRHandler* hostPDRHandler,
55             pldm::state_sensor::DbusToPLDMEvent* dbusToPLDMEventHandler,
56             fru::Handler* fruHandler,
57             pldm::responder::platform_config::Handler* platformConfigHandler,
58             pldm::requester::Handler<pldm::requester::Request>* handler,
59             sdeventplus::Event& event, bool buildPDRLazily = false,
60             const std::optional<EventMap>& addOnHandlersMap = std::nullopt) :
61         eid(eid), instanceIdDb(instanceIdDb), pdrRepo(repo),
62         hostPDRHandler(hostPDRHandler),
63         dbusToPLDMEventHandler(dbusToPLDMEventHandler), fruHandler(fruHandler),
64         dBusIntf(dBusIntf), platformConfigHandler(platformConfigHandler),
65         handler(handler), event(event), pdrJsonDir(pdrJsonDir),
66         pdrCreated(false), pdrJsonsDir({pdrJsonDir})
67     {
68         if (!buildPDRLazily)
69         {
70             generateTerminusLocatorPDR(pdrRepo);
71             generate(*dBusIntf, pdrJsonsDir, pdrRepo);
72             pdrCreated = true;
73         }
74 
75         handlers.emplace(
76             PLDM_GET_PDR,
__anon58b9ed2e0102(pldm_tid_t, const pldm_msg* request, size_t payloadLength) 77             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
78                 return this->getPDR(request, payloadLength);
79             });
80         handlers.emplace(
81             PLDM_SET_NUMERIC_EFFECTER_VALUE,
__anon58b9ed2e0202(pldm_tid_t, const pldm_msg* request, size_t payloadLength) 82             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
83                 return this->setNumericEffecterValue(request, payloadLength);
84             });
85         handlers.emplace(
86             PLDM_GET_NUMERIC_EFFECTER_VALUE,
__anon58b9ed2e0302(pldm_tid_t, const pldm_msg* request, size_t payloadLength) 87             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
88                 return this->getNumericEffecterValue(request, payloadLength);
89             });
90         handlers.emplace(
91             PLDM_SET_STATE_EFFECTER_STATES,
__anon58b9ed2e0402(pldm_tid_t, const pldm_msg* request, size_t payloadLength) 92             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
93                 return this->setStateEffecterStates(request, payloadLength);
94             });
95         handlers.emplace(
96             PLDM_PLATFORM_EVENT_MESSAGE,
__anon58b9ed2e0502(pldm_tid_t, const pldm_msg* request, size_t payloadLength) 97             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
98                 return this->platformEventMessage(request, payloadLength);
99             });
100         handlers.emplace(
101             PLDM_GET_STATE_SENSOR_READINGS,
__anon58b9ed2e0602(pldm_tid_t, const pldm_msg* request, size_t payloadLength) 102             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
103                 return this->getStateSensorReadings(request, payloadLength);
104             });
105 
106         // Default handler for PLDM Events
107         eventHandlers[PLDM_SENSOR_EVENT].emplace_back(
108             [this](const pldm_msg* request, size_t payloadLength,
__anon58b9ed2e0702(const pldm_msg* request, size_t payloadLength, uint8_t formatVersion, uint8_t tid, size_t eventDataOffset) 109                    uint8_t formatVersion, uint8_t tid, size_t eventDataOffset) {
110                 return this->sensorEvent(request, payloadLength, formatVersion,
111                                          tid, eventDataOffset);
112             });
113         eventHandlers[PLDM_PDR_REPOSITORY_CHG_EVENT].emplace_back(
114             [this](const pldm_msg* request, size_t payloadLength,
__anon58b9ed2e0802(const pldm_msg* request, size_t payloadLength, uint8_t formatVersion, uint8_t tid, size_t eventDataOffset) 115                    uint8_t formatVersion, uint8_t tid, size_t eventDataOffset) {
116                 return this->pldmPDRRepositoryChgEvent(
117                     request, payloadLength, formatVersion, tid,
118                     eventDataOffset);
119             });
120 
121         // Additional OEM event handlers for PLDM events, append it to the
122         // standard handlers
123         if (addOnHandlersMap)
124         {
125             auto addOnHandlers = addOnHandlersMap.value();
126             for (EventMap::iterator iter = addOnHandlers.begin();
127                  iter != addOnHandlers.end(); ++iter)
128             {
129                 auto search = eventHandlers.find(iter->first);
130                 if (search != eventHandlers.end())
131                 {
132                     search->second.insert(std::end(search->second),
133                                           std::begin(iter->second),
134                                           std::end(iter->second));
135                 }
136                 else
137                 {
138                     eventHandlers.emplace(iter->first, iter->second);
139                 }
140             }
141         }
142     }
143 
getRepo()144     pdr_utils::Repo& getRepo()
145     {
146         return this->pdrRepo;
147     }
148 
149     /** @brief Add D-Bus mapping and value mapping(stateId to D-Bus) for the
150      *         Id. If the same id is added, the previous dbusObjs will
151      *         be "over-written".
152      *
153      *  @param[in] Id - effecter/sensor id
154      *  @param[in] dbusObj - list of D-Bus object structure and list of D-Bus
155      *                       property value to attribute value
156      *  @param[in] typeId - the type id of enum
157      */
158     void addDbusObjMaps(
159         uint16_t id,
160         std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
161         pldm::responder::pdr_utils::TypeId typeId =
162             pldm::responder::pdr_utils::TypeId::PLDM_EFFECTER_ID);
163 
164     /** @brief Retrieve an id -> D-Bus objects mapping
165      *
166      *  @param[in] Id - id
167      *  @param[in] typeId - the type id of enum
168      *
169      *  @return std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> -
170      *          list of D-Bus object structure and list of D-Bus property value
171      *          to attribute value
172      */
173     const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
174         getDbusObjMaps(
175             uint16_t id,
176             pldm::responder::pdr_utils::TypeId typeId =
177                 pldm::responder::pdr_utils::TypeId::PLDM_EFFECTER_ID) const;
178 
getNextEffecterId()179     uint16_t getNextEffecterId()
180     {
181         return ++nextEffecterId;
182     }
183 
getNextSensorId()184     uint16_t getNextSensorId()
185     {
186         return ++nextSensorId;
187     }
188 
189     /** @brief Parse PDR JSONs and build PDR repository
190      *
191      *  @param[in] dBusIntf - The interface object
192      *  @param[in] dir - directory housing platform specific PDR JSON files
193      *  @param[in] repo - instance of concrete implementation of Repo
194      */
195     void generate(const pldm::utils::DBusHandler& dBusIntf,
196                   const std::vector<fs::path>& dir,
197                   pldm::responder::pdr_utils::Repo& repo);
198 
199     /** @brief Parse PDR JSONs and build state effecter PDR repository
200      *
201      *  @param[in] json - platform specific PDR JSON files
202      *  @param[in] repo - instance of state effecter implementation of Repo
203      */
204     void generateStateEffecterRepo(const pldm::utils::Json& json,
205                                    pldm::responder::pdr_utils::Repo& repo);
206 
207     /** @brief map of PLDM event type to EventHandlers
208      *
209      */
210     EventMap eventHandlers;
211 
212     /* @brief Method to set the oem platform handler in platform handler class
213      *
214      * @param[in] handler - oem platform handler
215      */
216     inline void
setOemPlatformHandler(pldm::responder::oem_platform::Handler * handler)217         setOemPlatformHandler(pldm::responder::oem_platform::Handler* handler)
218     {
219         oemPlatformHandler = handler;
220     }
221 
222     /* @brief Method to register event handlers
223      *
224      * @param[in] handler - oem event handlers
225      */
registerEventHandlers(EventType eventId,EventHandlers handlers)226     inline void registerEventHandlers(EventType eventId, EventHandlers handlers)
227     {
228         // Try to emplace the eventId with an empty vector if it doesn't exist
229         auto [iter,
230               inserted] = eventHandlers.try_emplace(eventId, EventHandlers{});
231 
232         for (const auto& handler : handlers)
233         {
234             iter->second.emplace_back(handler);
235         }
236     }
237 
238     /** @brief Handler for GetPDR
239      *
240      *  @param[in] request - Request message payload
241      *  @param[in] payloadLength - Request payload length
242      *  @param[out] Response - Response message written here
243      */
244     Response getPDR(const pldm_msg* request, size_t payloadLength);
245 
246     /** @brief Handler for setNumericEffecterValue
247      *
248      *  @param[in] request - Request message
249      *  @param[in] payloadLength - Request payload length
250      *  @return Response - PLDM Response message
251      */
252     Response setNumericEffecterValue(const pldm_msg* request,
253                                      size_t payloadLength);
254 
255     /** @brief Handler for getNumericEffecterValue
256      *
257      *  @param[in] request - Request message
258      *  @param[in] payloadLength - Request payload length
259      *  @return Response - PLDM Response message
260      */
261     Response getNumericEffecterValue(const pldm_msg* request,
262                                      size_t payloadLength);
263 
264     /** @brief Handler for getStateSensorReadings
265      *
266      *  @param[in] request - Request message
267      *  @param[in] payloadLength - Request payload length
268      *  @return Response - PLDM Response message
269      */
270     Response getStateSensorReadings(const pldm_msg* request,
271                                     size_t payloadLength);
272 
273     /** @brief Handler for setStateEffecterStates
274      *
275      *  @param[in] request - Request message
276      *  @param[in] payloadLength - Request payload length
277      *  @return Response - PLDM Response message
278      */
279     Response setStateEffecterStates(const pldm_msg* request,
280                                     size_t payloadLength);
281 
282     /** @brief Handler for PlatformEventMessage
283      *
284      *  @param[in] request - Request message
285      *  @param[in] payloadLength - Request payload length
286      *  @return Response - PLDM Response message
287      */
288     Response platformEventMessage(const pldm_msg* request,
289                                   size_t payloadLength);
290 
291     /** @brief Handler for event class Sensor event
292      *
293      *  @param[in] request - Request message
294      *  @param[in] payloadLength - Request payload length
295      *  @param[in] formatVersion - Version of the event format
296      *  @param[in] tid - Terminus ID of the event's originator
297      *  @param[in] eventDataOffset - Offset of the event data in the request
298      *                               message
299      *  @return PLDM completion code
300      */
301     int sensorEvent(const pldm_msg* request, size_t payloadLength,
302                     uint8_t formatVersion, uint8_t tid, size_t eventDataOffset);
303 
304     /** @brief Handler for pldmPDRRepositoryChgEvent
305      *
306      *  @param[in] request - Request message
307      *  @param[in] payloadLength - Request payload length
308      *  @param[in] formatVersion - Version of the event format
309      *  @param[in] tid - Terminus ID of the event's originator
310      *  @param[in] eventDataOffset - Offset of the event data in the request
311      *                               message
312      *  @return PLDM completion code
313      */
314     int pldmPDRRepositoryChgEvent(const pldm_msg* request, size_t payloadLength,
315                                   uint8_t formatVersion, uint8_t tid,
316                                   size_t eventDataOffset);
317 
318     /** @brief Handler for extracting the PDR handles from changeEntries
319      *
320      *  @param[in] changeEntryData - ChangeEntry data from changeRecord
321      *  @param[in] changeEntryDataSize - total size of changeEntryData
322      *  @param[in] numberOfChangeEntries - total number of changeEntries to
323      *                                     extract
324      *  @param[out] pdrRecordHandles - std::vector where the extracted PDR
325      *                                 handles are placed
326      *  @return PLDM completion code
327      */
328     int getPDRRecordHandles(const ChangeEntry* changeEntryData,
329                             size_t changeEntryDataSize,
330                             size_t numberOfChangeEntries,
331                             PDRRecordHandles& pdrRecordHandles);
332 
333     /** @brief Function to set the effecter requested by pldm requester
334      *  @param[in] dBusIntf - The interface object
335      *  @param[in] effecterId - Effecter ID sent by the requester to act on
336      *  @param[in] stateField - The state field data for each of the states,
337      * equal to composite effecter count in number
338      *  @return - Success or failure in setting the states. Returns failure in
339      * terms of PLDM completion codes if at least one state fails to be set
340      */
341     template <class DBusInterface>
setStateEffecterStatesHandler(const DBusInterface & dBusIntf,uint16_t effecterId,const std::vector<set_effecter_state_field> & stateField)342     int setStateEffecterStatesHandler(
343         const DBusInterface& dBusIntf, uint16_t effecterId,
344         const std::vector<set_effecter_state_field>& stateField)
345     {
346         using namespace pldm::responder::pdr;
347         using namespace pldm::utils;
348         using StateSetNum = uint8_t;
349 
350         state_effecter_possible_states* states = nullptr;
351         pldm_state_effecter_pdr* pdr = nullptr;
352         uint8_t compEffecterCnt = stateField.size();
353 
354         std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)>
355             stateEffecterPdrRepo(pldm_pdr_init(), pldm_pdr_destroy);
356         if (!stateEffecterPdrRepo)
357         {
358             throw std::runtime_error(
359                 "Failed to instantiate state effecter PDR repository");
360         }
361         pldm::responder::pdr_utils::Repo stateEffecterPDRs(
362             stateEffecterPdrRepo.get());
363         getRepoByType(pdrRepo, stateEffecterPDRs, PLDM_STATE_EFFECTER_PDR);
364         if (stateEffecterPDRs.empty())
365         {
366             error("Failed to get record by PDR type");
367             return PLDM_PLATFORM_INVALID_EFFECTER_ID;
368         }
369 
370         pldm::responder::pdr_utils::PdrEntry pdrEntry{};
371         auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
372         while (pdrRecord)
373         {
374             pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
375             if (pdr->effecter_id != effecterId)
376             {
377                 pdr = nullptr;
378                 pdrRecord =
379                     stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
380                 continue;
381             }
382 
383             states = reinterpret_cast<state_effecter_possible_states*>(
384                 pdr->possible_states);
385             if (compEffecterCnt > pdr->composite_effecter_count)
386             {
387                 error(
388                     "The requester sent wrong composite effecter count '{COMPOSITE_EFFECTER_COUNT}' for the effecter ID '{EFFECTERID}'.",
389                     "COMPOSITE_EFFECTER_COUNT", compEffecterCnt, "EFFECTERID",
390                     effecterId);
391                 return PLDM_ERROR_INVALID_DATA;
392             }
393             break;
394         }
395 
396         if (!pdr)
397         {
398             return PLDM_PLATFORM_INVALID_EFFECTER_ID;
399         }
400 
401         int rc = PLDM_SUCCESS;
402         try
403         {
404             const auto& [dbusMappings, dbusValMaps] =
405                 effecterDbusObjMaps.at(effecterId);
406             for (uint8_t currState = 0; currState < compEffecterCnt;
407                  ++currState)
408             {
409                 std::vector<StateSetNum> allowed{};
410                 // computation is based on table 79 from DSP0248 v1.1.1
411                 uint8_t bitfieldIndex =
412                     stateField[currState].effecter_state / 8;
413                 uint8_t bit = stateField[currState].effecter_state -
414                               (8 * bitfieldIndex);
415                 if (states->possible_states_size < bitfieldIndex ||
416                     !(states->states[bitfieldIndex].byte & (1 << bit)))
417                 {
418                     error(
419                         "Invalid state set value for effecter ID '{EFFECTERID}', effecter state '{EFFECTER_STATE}', composite effecter ID '{COMPOSITE_EFFECTER_ID}' and path '{PATH}'.",
420                         "EFFECTERID", effecterId, "EFFECTER_STATE",
421                         stateField[currState].effecter_state,
422                         "COMPOSITE_EFFECTER_COUNT", currState, "PATH",
423                         dbusMappings[currState].objectPath);
424                     rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
425                     break;
426                 }
427                 const DBusMapping& dbusMapping = dbusMappings[currState];
428                 const pldm::responder::pdr_utils::StatestoDbusVal&
429                     dbusValToMap = dbusValMaps[currState];
430 
431                 if (stateField[currState].set_request == PLDM_REQUEST_SET)
432                 {
433                     try
434                     {
435                         dBusIntf.setDbusProperty(
436                             dbusMapping,
437                             dbusValToMap.at(
438                                 stateField[currState].effecter_state));
439                     }
440                     catch (const std::exception& e)
441                     {
442                         error(
443                             "Failed to set property '{PROPERTY}' of interface '{INTERFACE}' at path '{PATH}', error - {ERROR}",
444                             "PROPERTY", dbusMapping.propertyName, "DBUS_INTF",
445                             dbusMapping.interface, "DBUS_OBJ_PATH",
446                             dbusMapping.objectPath, "ERROR", e);
447                         return PLDM_ERROR;
448                     }
449                 }
450                 uint8_t* nextState =
451                     reinterpret_cast<uint8_t*>(states) +
452                     sizeof(state_effecter_possible_states) -
453                     sizeof(states->states) +
454                     (states->possible_states_size * sizeof(states->states));
455                 states = reinterpret_cast<state_effecter_possible_states*>(
456                     nextState);
457             }
458         }
459         catch (const std::out_of_range& e)
460         {
461             error(
462                 "The effecter ID '{EFFECTERID}' does not exist, error - {ERROR}.",
463                 "EFFECTERID", effecterId, "ERROR", e);
464         }
465 
466         return rc;
467     }
468 
469     /** @brief Build BMC Terminus Locator PDR
470      *
471      *  @param[in] repo - instance of concrete implementation of Repo
472      */
473     void generateTerminusLocatorPDR(pldm::responder::pdr_utils::Repo& repo);
474 
475     /** @brief Get std::map associated with the entity
476      *         key: object path
477      *         value: pldm_entity
478      *
479      *  @return std::map<ObjectPath, pldm_entity>
480      */
getAssociateEntityMap() const481     inline const AssociatedEntityMap& getAssociateEntityMap() const
482     {
483         if (fruHandler == nullptr)
484         {
485             throw InternalFailure();
486         }
487         return fruHandler->getAssociateEntityMap();
488     }
489 
490     /** @brief update the sensor cache map
491      *  @param[in] sensorId - sensor id that needs an update
492      *  @param[in] sensorRearm - rearm value within the sensor
493      *  @param[in] value - value that needs to be cached
494      */
495 
updateSensorCache(pldm::pdr::SensorID sensorId,size_t sensorRearm,uint8_t value)496     inline void updateSensorCache(pldm::pdr::SensorID sensorId,
497                                   size_t sensorRearm, uint8_t value)
498     {
499         if (dbusToPLDMEventHandler)
500         {
501             dbusToPLDMEventHandler->updateSensorCacheMaps(sensorId, sensorRearm,
502                                                           value);
503         }
504     }
505 
506     /** @brief process the actions that needs to be performed after a GetPDR
507      *         call is received
508      *  @param[in] source - sdeventplus event source
509      */
510     void _processPostGetPDRActions(sdeventplus::source::EventBase& source);
511 
512     /** @brief Method for setEventreceiver */
513     void setEventReceiver();
514 
515   private:
516     uint8_t eid;
517     InstanceIdDb* instanceIdDb;
518     pdr_utils::Repo pdrRepo;
519     uint16_t nextEffecterId{};
520     uint16_t nextSensorId{};
521     DbusObjMaps effecterDbusObjMaps{};
522     DbusObjMaps sensorDbusObjMaps{};
523     HostPDRHandler* hostPDRHandler;
524     pldm::state_sensor::DbusToPLDMEvent* dbusToPLDMEventHandler;
525     fru::Handler* fruHandler;
526     const pldm::utils::DBusHandler* dBusIntf;
527     pldm::responder::oem_platform::Handler* oemPlatformHandler = nullptr;
528     pldm::responder::platform_config::Handler* platformConfigHandler;
529     pldm::requester::Handler<pldm::requester::Request>* handler;
530     sdeventplus::Event& event;
531     fs::path pdrJsonDir;
532     bool pdrCreated;
533     std::vector<fs::path> pdrJsonsDir;
534     std::unique_ptr<sdeventplus::source::Defer> deferredGetPDREvent;
535 };
536 
537 /** @brief Function to check if a sensor falls in OEM range
538  *         A sensor is considered to be oem if either of entity
539  *         type or state set or both falls in oem range
540  *
541  *  @param[in] handler - the interface object
542  *  @param[in] sensorId - sensor id
543  *  @param[in] sensorRearmCount - sensor rearm count
544  *  @param[out] compSensorCnt - composite sensor count
545  *  @param[out] entityType - entity type
546  *  @param[out] entityInstance - entity instance number
547  *  @param[out] stateSetId - state set id
548  *  @param[out] containerId - container id
549  *
550  *  @return true if the sensor is OEM. All out parameters are invalid
551  *               for a non OEM sensor
552  */
553 bool isOemStateSensor(Handler& handler, uint16_t sensorId,
554                       uint8_t sensorRearmCount, uint8_t& compSensorCnt,
555                       uint16_t& entityType, uint16_t& entityInstance,
556                       uint16_t& stateSetId, uint16_t& containerId);
557 
558 /** @brief Function to check if an effecter falls in OEM range
559  *         An effecter is considered to be oem if either of entity
560  *         type or state set or both falls in oem range
561  *
562  *  @param[in] handler - the interface object
563  *  @param[in] effecterId - effecter id
564  *  @param[in] compEffecterCnt - composite effecter count
565  *  @param[out] entityType - entity type
566  *  @param[out] entityInstance - entity instance number
567  *  @param[out] stateSetId - state set id
568  *
569  *  @return true if the effecter is OEM. All out parameters are invalid
570  *               for a non OEM effecter
571  */
572 bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
573                         uint8_t compEffecterCnt, uint16_t& entityType,
574                         uint16_t& entityInstance, uint16_t& stateSetId);
575 
576 } // namespace platform
577 } // namespace responder
578 } // namespace pldm
579