pldm: Optimized the setXXXHandler method in platform.hpp

Since other PDR types(eg: numeric effecter PDR) need to be added later,
all setXXXHandler methods are best separated, which is easy to maintain
and read.
so moved the setStateEffecterStateHandler method to
platform_state_effecter.hpp.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Iae120541963f3026e303f38f7960f51434be9de3
diff --git a/libpldmresponder/platform_state_effecter.hpp b/libpldmresponder/platform_state_effecter.hpp
new file mode 100644
index 0000000..7584a67
--- /dev/null
+++ b/libpldmresponder/platform_state_effecter.hpp
@@ -0,0 +1,155 @@
+#pragma once
+
+#include "config.h"
+
+#include "handler.hpp"
+#include "libpldmresponder/pdr.hpp"
+#include "pdr_utils.hpp"
+#include "utils.hpp"
+
+#include <cstdint>
+#include <map>
+
+#include "libpldm/platform.h"
+#include "libpldm/states.h"
+
+using namespace pldm::responder::pdr;
+
+namespace pldm
+{
+namespace responder
+{
+namespace platform_state_effecter
+{
+/** @brief Function to set the effecter requested by pldm requester
+ *
+ *  @tparam[in] DBusInterface - DBus interface type
+ *  @tparam[in] Handler - pldm::responder::platform::Handler
+ *  @param[in] dBusIntf - The interface object of DBusInterface
+ *  @param[in] handler - The interface object of
+ *             pldm::responder::platform::Handler
+ *  @param[in] effecterId - Effecter ID sent by the requester to act on
+ *  @param[in] stateField - The state field data for each of the states,
+ * equal to composite effecter count in number
+ *  @return - Success or failure in setting the states. Returns failure in
+ * terms of PLDM completion codes if atleast one state fails to be set
+ */
+template <class DBusInterface, class Handler>
+int setStateEffecterStatesHandler(
+    const DBusInterface& dBusIntf, Handler& handler, uint16_t effecterId,
+    const std::vector<set_effecter_state_field>& stateField)
+{
+    using namespace pldm::responder::pdr;
+    using namespace pldm::utils;
+    using StateSetNum = uint8_t;
+
+    state_effecter_possible_states* states = nullptr;
+    pldm_state_effecter_pdr* pdr = nullptr;
+    uint8_t compEffecterCnt = stateField.size();
+
+    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
+        pldm_pdr_init(), pldm_pdr_destroy);
+    Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
+    getRepoByType(handler.getRepo(), stateEffecterPDRs,
+                  PLDM_STATE_EFFECTER_PDR);
+    if (stateEffecterPDRs.empty())
+    {
+        std::cerr << "Failed to get record by PDR type\n";
+        return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+    }
+
+    PdrEntry pdrEntry{};
+    auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
+    while (pdrRecord)
+    {
+        pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
+        if (pdr->effecter_id != effecterId)
+        {
+            pdr = nullptr;
+            pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
+            continue;
+        }
+
+        states = reinterpret_cast<state_effecter_possible_states*>(
+            pdr->possible_states);
+        if (compEffecterCnt > pdr->composite_effecter_count)
+        {
+            std::cerr << "The requester sent wrong composite effecter"
+                      << " count for the effecter, EFFECTER_ID=" << effecterId
+                      << "COMP_EFF_CNT=" << compEffecterCnt << "\n";
+            return PLDM_ERROR_INVALID_DATA;
+        }
+        break;
+    }
+
+    if (!pdr)
+    {
+        return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+    }
+
+    int rc = PLDM_SUCCESS;
+    try
+    {
+        const auto& [dbusMappings, dbusValMaps] =
+            handler.getDbusObjMaps(effecterId);
+        for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
+        {
+            std::vector<StateSetNum> allowed{};
+            // computation is based on table 79 from DSP0248 v1.1.1
+            uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
+            uint8_t bit =
+                stateField[currState].effecter_state - (8 * bitfieldIndex);
+            if (states->possible_states_size < bitfieldIndex ||
+                !(states->states[bitfieldIndex].byte & (1 << bit)))
+            {
+                std::cerr << "Invalid state set value, EFFECTER_ID="
+                          << effecterId
+                          << " VALUE=" << stateField[currState].effecter_state
+                          << " COMPOSITE_EFFECTER_ID=" << currState
+                          << " DBUS_PATH=" << dbusMappings[currState].objectPath
+                          << "\n";
+                rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
+                break;
+            }
+            const DBusMapping& dbusMapping = dbusMappings[currState];
+            const StatestoDbusVal& dbusValToMap = dbusValMaps[currState];
+
+            if (stateField[currState].set_request == PLDM_REQUEST_SET)
+            {
+                try
+                {
+                    dBusIntf.setDbusProperty(
+                        dbusMapping,
+                        dbusValToMap.at(stateField[currState].effecter_state));
+                }
+                catch (const std::exception& e)
+                {
+                    std::cerr
+                        << "Error setting property, ERROR=" << e.what()
+                        << " PROPERTY=" << dbusMapping.propertyName
+                        << " INTERFACE=" << dbusMapping.interface << " PATH="
+                        << dbusMapping.objectPath << "\n";
+                    return PLDM_ERROR;
+                }
+            }
+            uint8_t* nextState =
+                reinterpret_cast<uint8_t*>(states) +
+                sizeof(state_effecter_possible_states) -
+                sizeof(states->states) +
+                (states->possible_states_size * sizeof(states->states));
+            states =
+                reinterpret_cast<state_effecter_possible_states*>(nextState);
+        }
+    }
+    catch (const std::out_of_range& e)
+    {
+        std::cerr << "the effecterId does not exist. effecter id: "
+                  << effecterId << e.what() << '\n';
+    }
+
+    return rc;
+}
+
+} // namespace platform_state_effecter
+} // namespace responder
+} // namespace pldm