libpldmresponder:Support GetNumericEffecterValue responder

The GetNumericEffecterValue command is used to return the present
numeric setting of a PLDM Numeric Effecter.
This commit adds responder support for GetNumericEffecterValue Cmd
as mentioned in Section22.3 of DSP0248_1.2.0.
Currently "effecterOperationalState" field in the response msg is
set to "enabled-noUpdatePending". Actual value can be fetched once
the support for EffecterEvent/SetNumericEffecterEnable is added.

Test:
    Using pldmtool raw command
    Success Case:
        pldmtool raw -d 0x80 0x02 0x32 0x23 00
        pldmtool: Tx: 08 01 80 02 32 23 00
        pldmtool: Rx: 08 01 00 02 32 00 00 01 03 03
   Failure Case:
        pldmtool raw -d 0x80 0x02 0x32 0x25 0x00
        pldmtool: Tx: 08 01 80 02 32 25 00
        pldmtool: Rx: 08 01 00 02 32 80

Change-Id: I64a7205d8f69e3925b75b02558a0857b63c70ebf
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
diff --git a/libpldmresponder/test/libpldmresponder_platform_test.cpp b/libpldmresponder/test/libpldmresponder_platform_test.cpp
index a646f9d..2d52987 100644
--- a/libpldmresponder/test/libpldmresponder_platform_test.cpp
+++ b/libpldmresponder/test/libpldmresponder_platform_test.cpp
@@ -395,6 +395,123 @@
     pldm_pdr_destroy(numericEffecterPdrRepo);
 }
 
+TEST(getNumericEffecterValueHandler, testGoodRequest)
+{
+    MockdBusHandler mockedUtils;
+    EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
+        .Times(5)
+        .WillRepeatedly(Return("foo.bar"));
+
+    auto inPDRRepo = pldm_pdr_init();
+    auto numericEffecterPdrRepo = pldm_pdr_init();
+    Repo numericEffecterPDRs(numericEffecterPdrRepo);
+    auto event = sdeventplus::Event::get_default();
+    Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
+                    nullptr, nullptr, nullptr, nullptr, event);
+    Repo inRepo(inPDRRepo);
+    getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR);
+
+    pdr_utils::PdrEntry e;
+    auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e);
+    ASSERT_NE(record4, nullptr);
+
+    pldm_numeric_effecter_value_pdr* pdr =
+        reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data);
+    EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR);
+
+    uint16_t effecterId = 3;
+
+    uint8_t effecterDataSize{};
+    pldm::utils::PropertyValue dbusValue;
+    std::string propertyType;
+
+    // effecterValue return the present numeric setting
+    uint32_t effecterValue = 2100000000;
+    using effecterOperationalState = uint8_t;
+    using completionCode = uint8_t;
+
+    EXPECT_CALL(mockedUtils,
+                getDbusPropertyVariant(StrEq("/foo/bar"), StrEq("propertyName"),
+                                       StrEq("xyz.openbmc_project.Foo.Bar")))
+        .WillOnce(Return(PropertyValue(static_cast<uint64_t>(effecterValue))));
+
+    auto rc = platform_numeric_effecter::getNumericEffecterData<MockdBusHandler,
+                                                                Handler>(
+        mockedUtils, handler, effecterId, effecterDataSize, propertyType,
+        dbusValue);
+
+    ASSERT_EQ(rc, 0);
+
+    size_t responsePayloadLength = sizeof(completionCode) +
+                                   sizeof(effecterDataSize) +
+                                   sizeof(effecterOperationalState) +
+                                   getEffecterDataSize(effecterDataSize) +
+                                   getEffecterDataSize(effecterDataSize);
+
+    Response response(responsePayloadLength + sizeof(pldm_msg_hdr));
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    rc = platform_numeric_effecter::getNumericEffecterValueHandler(
+        propertyType, dbusValue, effecterDataSize, responsePtr,
+        responsePayloadLength, 1);
+
+    ASSERT_EQ(rc, 0);
+
+    struct pldm_get_numeric_effecter_value_resp* resp =
+        reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+            responsePtr->payload);
+    ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
+    uint32_t valPresent;
+    memcpy(&valPresent, &resp->pending_and_present_values[4],
+           sizeof(valPresent));
+
+    ASSERT_EQ(effecterValue, valPresent);
+
+    pldm_pdr_destroy(inPDRRepo);
+    pldm_pdr_destroy(numericEffecterPdrRepo);
+}
+
+TEST(getNumericEffecterValueHandler, testBadRequest)
+{
+    MockdBusHandler mockedUtils;
+    EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
+        .Times(5)
+        .WillRepeatedly(Return("foo.bar"));
+
+    auto inPDRRepo = pldm_pdr_init();
+    auto numericEffecterPdrRepo = pldm_pdr_init();
+    Repo numericEffecterPDRs(numericEffecterPdrRepo);
+    auto event = sdeventplus::Event::get_default();
+    Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
+                    nullptr, nullptr, nullptr, nullptr, event);
+    Repo inRepo(inPDRRepo);
+    getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR);
+
+    pdr_utils::PdrEntry e;
+    auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e);
+    ASSERT_NE(record4, nullptr);
+
+    pldm_numeric_effecter_value_pdr* pdr =
+        reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data);
+    EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR);
+
+    uint16_t effecterId = 4;
+
+    uint8_t effecterDataSize{};
+    pldm::utils::PropertyValue dbusValue;
+    std::string propertyType;
+
+    auto rc = platform_numeric_effecter::getNumericEffecterData<MockdBusHandler,
+                                                                Handler>(
+        mockedUtils, handler, effecterId, effecterDataSize, propertyType,
+        dbusValue);
+
+    ASSERT_EQ(rc, 128);
+
+    pldm_pdr_destroy(inPDRRepo);
+    pldm_pdr_destroy(numericEffecterPdrRepo);
+}
+
 TEST(parseStateSensor, allScenarios)
 {
     // Sample state sensor with SensorID - 1, EntityType - Processor Module(67)