pdr: Add decode_numeric_effecter_pdr_data()

Add `decode_numeric_effecter_pdr_data` API to decode the numeric
effecter PDR data in DSP0248_1.2.2 table 87. The API will be used to
retrieve the data fields of numeric effecter from the PDRs in `pldmd`.

Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: I323a1288cb0262bd39f4f28701ddc7dbb70c33c8
diff --git a/tests/libpldm_platform_test.cpp b/tests/libpldm_platform_test.cpp
index f3ec7e7..be08201 100644
--- a/tests/libpldm_platform_test.cpp
+++ b/tests/libpldm_platform_test.cpp
@@ -4137,3 +4137,721 @@
         decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
 }
+
+TEST(decodeNumericEffecterPdrData, Uint8Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        1,
+        0, // containerID=1
+        0x2,
+        0x0,                           // effecter_semantic_id=2
+        PLDM_NO_INIT,                  // effecterInit
+        false,                         // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
+        0,                             // unitModifier
+        0,                             // rateUnit
+        0,                             // baseOEMUnitHandle
+        0,                             // auxUnit
+        0,                             // auxUnitModifier
+        4,                             // auxRateUnit
+        0,                             // auxOEMUnitHandle
+        true,                          // isLinear
+        PLDM_EFFECTER_DATA_SIZE_UINT8, // effecterDataSize
+        0,
+        0,
+        0xc0,
+        0x3f, // resolution=1.5
+        0,
+        0,
+        0x80,
+        0x3f, // offset=1.0
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f,                          // transition_interval=1.0
+        255,                           // maxSetdable
+        0,                             // minSetable
+        PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
+        0x1f,                          // rangeFieldsupport
+        50,                            // nominalValue = 50
+        60,                            // normalMax = 60
+        40,                            // normalMin = 40
+        90,                            // rated_max = 90
+        10                             // rated_min = 10
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+    EXPECT_EQ(1, decodedPdr.hdr.record_handle);
+    EXPECT_EQ(1, decodedPdr.hdr.version);
+    EXPECT_EQ(PLDM_NUMERIC_EFFECTER_PDR, decodedPdr.hdr.type);
+    EXPECT_EQ(0, decodedPdr.hdr.record_change_num);
+    EXPECT_EQ(PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, decodedPdr.hdr.length);
+    EXPECT_EQ(1, decodedPdr.effecter_id);
+    EXPECT_EQ(PLDM_ENTITY_POWER_SUPPLY, decodedPdr.entity_type);
+    EXPECT_EQ(1, decodedPdr.entity_instance);
+    EXPECT_EQ(1, decodedPdr.container_id);
+    EXPECT_EQ(2, decodedPdr.effecter_semantic_id);
+    EXPECT_EQ(PLDM_NO_INIT, decodedPdr.effecter_init);
+    EXPECT_EQ(false, decodedPdr.effecter_auxiliary_names);
+    EXPECT_EQ(PLDM_SENSOR_UNIT_DEGRESS_C, decodedPdr.base_unit);
+    EXPECT_EQ(0, decodedPdr.unit_modifier);
+    EXPECT_EQ(0, decodedPdr.rate_unit);
+    EXPECT_EQ(0, decodedPdr.base_oem_unit_handle);
+    EXPECT_EQ(0, decodedPdr.aux_unit);
+    EXPECT_EQ(0, decodedPdr.aux_unit_modifier);
+    EXPECT_EQ(4, decodedPdr.aux_rate_unit);
+    EXPECT_EQ(0, decodedPdr.aux_oem_unit_handle);
+    EXPECT_EQ(true, decodedPdr.is_linear);
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_UINT8, decodedPdr.effecter_data_size);
+    EXPECT_FLOAT_EQ(1.5f, decodedPdr.resolution);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.offset);
+    EXPECT_EQ(0, decodedPdr.accuracy);
+    EXPECT_EQ(0, decodedPdr.plus_tolerance);
+    EXPECT_EQ(0, decodedPdr.minus_tolerance);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.state_transition_interval);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.transition_interval);
+    EXPECT_EQ(255, decodedPdr.max_settable.value_u8);
+    EXPECT_EQ(0, decodedPdr.min_settable.value_u8);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT8, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(50, decodedPdr.nominal_value.value_u8);
+    EXPECT_EQ(60, decodedPdr.normal_max.value_u8);
+    EXPECT_EQ(40, decodedPdr.normal_min.value_u8);
+    EXPECT_EQ(90, decodedPdr.rated_max.value_u8);
+    EXPECT_EQ(10, decodedPdr.rated_min.value_u8);
+}
+
+TEST(decodeNumericEffecterPdrData, Sint8Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                           // effecter_semantic_id=2
+        PLDM_NO_INIT,                  // effecterInit
+        false,                         // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
+        0,                             // unitModifier
+        0,                             // rateUnit
+        0,                             // baseOEMUnitHandle
+        0,                             // auxUnit
+        0,                             // auxUnitModifier
+        0,                             // auxRateUnit
+        0,                             // auxOEMUnitHandle
+        true,                          // isLinear
+        PLDM_RANGE_FIELD_FORMAT_SINT8, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f,                          // transition_interval=1.0
+        0x64,                          // maxSetdable = 100
+        0x9c,                          // minSetable = -100
+        PLDM_RANGE_FIELD_FORMAT_SINT8, // rangeFieldFormat
+        0x1f,                          // rangeFieldsupport
+        0,                             // nominalValue = 0
+        5,                             // normalMax = 5
+        0xfb,                          // normalMin = -5
+        30,                            // rated_max = 30
+        0xe2                           // rated_min = -30
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT8, decodedPdr.effecter_data_size);
+    EXPECT_EQ(100, decodedPdr.max_settable.value_s8);
+    EXPECT_EQ(-100, decodedPdr.min_settable.value_s8);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT8, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s8);
+    EXPECT_EQ(5, decodedPdr.normal_max.value_s8);
+    EXPECT_EQ(-5, decodedPdr.normal_min.value_s8);
+    EXPECT_EQ(30, decodedPdr.rated_max.value_s8);
+    EXPECT_EQ(-30, decodedPdr.rated_min.value_s8);
+}
+
+TEST(decodeNumericEffecterPdrData, Uint16Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                2 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 2,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_UINT16, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0,
+        0x10, // maxSetdable = 4096
+        0,
+        0,                              // minSetable = 0
+        PLDM_RANGE_FIELD_FORMAT_UINT16, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0x88,
+        0x13, // nominalValue = 5,000
+        0x70,
+        0x17, // normalMax = 6,000
+        0xa0,
+        0x0f, // normalMin = 4,000
+        0x28,
+        0x23, // rated_max = 9,000
+        0xe8,
+        0x03 // rated_min = 1,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_UINT16, decodedPdr.effecter_data_size);
+    EXPECT_EQ(4096, decodedPdr.max_settable.value_u16);
+    EXPECT_EQ(0, decodedPdr.min_settable.value_u16);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT16, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(5000, decodedPdr.nominal_value.value_u16);
+    EXPECT_EQ(6000, decodedPdr.normal_max.value_u16);
+    EXPECT_EQ(4000, decodedPdr.normal_min.value_u16);
+    EXPECT_EQ(9000, decodedPdr.rated_max.value_u16);
+    EXPECT_EQ(1000, decodedPdr.rated_min.value_u16);
+}
+
+TEST(decodeNumericEffecterPdrData, Sint16Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                2 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 2,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_SINT16, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0xe8,
+        0x03, // maxSetdable = 1000
+        0x18,
+        0xfc,                           // minSetable = -1000
+        PLDM_RANGE_FIELD_FORMAT_SINT16, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0,
+        0, // nominalValue = 0
+        0xf4,
+        0x01, // normalMax = 500
+        0x0c,
+        0xfe, // normalMin = -500
+        0xb8,
+        0x0b, // rated_max = 3,000
+        0x48,
+        0xf4 // rated_min = -3,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT16, decodedPdr.effecter_data_size);
+    EXPECT_EQ(1000, decodedPdr.max_settable.value_s16);
+    EXPECT_EQ(-1000, decodedPdr.min_settable.value_s16);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT16, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s16);
+    EXPECT_EQ(500, decodedPdr.normal_max.value_s16);
+    EXPECT_EQ(-500, decodedPdr.normal_min.value_s16);
+    EXPECT_EQ(3000, decodedPdr.rated_max.value_s16);
+    EXPECT_EQ(-3000, decodedPdr.rated_min.value_s16);
+}
+
+TEST(decodeNumericEffecterPdrData, Uint32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                4 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_UINT32, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0,
+        0x10,
+        0,
+        0, // maxSetdable = 4096
+        0,
+        0,
+        0,
+        0,                              // minSetable = 0
+        PLDM_RANGE_FIELD_FORMAT_UINT32, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0x40,
+        0x4b,
+        0x4c,
+        0x00, // nominalValue = 5,000,000
+        0x80,
+        0x8d,
+        0x5b,
+        0x00, // normalMax = 6,000,000
+        0x00,
+        0x09,
+        0x3d,
+        0x00, // normalMin = 4,000,000
+        0x40,
+        0x54,
+        0x89,
+        0x00, // rated_max = 9,000,000
+        0x40,
+        0x42,
+        0x0f,
+        0x00 // rated_min = 1,000,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_UINT32, decodedPdr.effecter_data_size);
+    EXPECT_EQ(4096, decodedPdr.max_settable.value_u32);
+    EXPECT_EQ(0, decodedPdr.min_settable.value_u32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_UINT32, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(5000000, decodedPdr.nominal_value.value_u32);
+    EXPECT_EQ(6000000, decodedPdr.normal_max.value_u32);
+    EXPECT_EQ(4000000, decodedPdr.normal_min.value_u32);
+    EXPECT_EQ(9000000, decodedPdr.rated_max.value_u32);
+    EXPECT_EQ(1000000, decodedPdr.rated_min.value_u32);
+}
+
+TEST(decodeNumericEffecterPdrData, Sint32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                4 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_SINT32, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0xa0,
+        0x86,
+        0x01,
+        0x00, // maxSetdable = 100000
+        0x60,
+        0x79,
+        0xfe,
+        0xff,                           // minSetable = -10000
+        PLDM_RANGE_FIELD_FORMAT_SINT32, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0,
+        0,
+        0,
+        0, // nominalValue = 0
+        0x20,
+        0xa1,
+        0x07,
+        0x00, // normalMax = 500,000
+        0xe0,
+        0x5e,
+        0xf8,
+        0xff, // normalMin = -500,000
+        0xc0,
+        0xc6,
+        0x2d,
+        0x00, // rated_max = 3,000,000
+        0x40,
+        0x39,
+        0xd2,
+        0xff // rated_min = -3,000,000
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT32, decodedPdr.effecter_data_size);
+    EXPECT_EQ(100000, decodedPdr.max_settable.value_s32);
+    EXPECT_EQ(-100000, decodedPdr.min_settable.value_s32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_SINT32, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_EQ(0, decodedPdr.nominal_value.value_s32);
+    EXPECT_EQ(500000, decodedPdr.normal_max.value_s32);
+    EXPECT_EQ(-500000, decodedPdr.normal_min.value_s32);
+    EXPECT_EQ(3000000, decodedPdr.rated_max.value_s32);
+    EXPECT_EQ(-3000000, decodedPdr.rated_min.value_s32);
+}
+
+TEST(decodeNumericEffecterPdrData, Real32Test)
+{
+    std::vector<uint8_t> pdr1{
+        0x1,
+        0x0,
+        0x0,
+        0x0,                       // record handle
+        0x1,                       // PDRHeaderVersion
+        PLDM_NUMERIC_EFFECTER_PDR, // PDRType
+        0x0,
+        0x0, // recordChangeNumber
+        PLDM_PDR_NUMERIC_EFFECTER_PDR_FIXED_LENGTH +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_EFFECTER_DATA_SIZE_MIN_LENGTH *
+                4 +
+            PLDM_PDR_NUMERIC_EFFECTER_PDR_VARIED_RANGE_FIELD_MIN_LENGTH * 4,
+        0, // dataLength
+        0,
+
+        0, // PLDMTerminusHandle
+        0x1,
+        0x0, // effecterID=1
+        PLDM_ENTITY_POWER_SUPPLY,
+        0, // entityType=Power Supply(120)
+        1,
+        0, // entityInstanceNumber
+        0x1,
+        0x0, // containerID=1
+        0x2,
+        0x0,                            // effecter_semantic_id=2
+        PLDM_NO_INIT,                   // effecterInit
+        false,                          // effecterAuxiliaryNames
+        PLDM_SENSOR_UNIT_DEGRESS_C,     // baseUint(2)=degrees C
+        0,                              // unitModifier
+        0,                              // rateUnit
+        0,                              // baseOEMUnitHandle
+        0,                              // auxUnit
+        0,                              // auxUnitModifier
+        0,                              // auxRateUnit
+        0,                              // auxOEMUnitHandle
+        true,                           // isLinear
+        PLDM_EFFECTER_DATA_SIZE_SINT32, // effecterDataSize
+        0,
+        0,
+        0,
+        0, // resolution
+        0,
+        0,
+        0,
+        0, // offset
+        0,
+        0, // accuracy
+        0, // plusTolerance
+        0, // minusTolerance
+        0,
+        0,
+        0x80,
+        0x3f, // stateTransistionInterval=1.0
+        0,
+        0,
+        0x80,
+        0x3f, // transition_interval=1.0
+        0xa0,
+        0x86,
+        0x01,
+        0x00, // maxSetdable = 100000
+        0x60,
+        0x79,
+        0xfe,
+        0xff,                           // minSetable = -10000
+        PLDM_RANGE_FIELD_FORMAT_REAL32, // rangeFieldFormat
+        0x1f,                           // rangeFieldsupport
+        0,
+        0,
+        0,
+        0, // nominalValue = 0.0
+        0x33,
+        0x33,
+        0x48,
+        0x42, // normalMax = 50.05
+        0x33,
+        0x33,
+        0x48,
+        0xc2, // normalMin = -50.05
+        0x62,
+        0x00,
+        0x96,
+        0x43, // rated_max = 300.003
+        0x62,
+        0x00,
+        0x96,
+        0xc3 // rated_min = -300.003
+    };
+
+    struct pldm_numeric_effecter_value_pdr decodedPdr;
+    auto rc =
+        decode_numeric_effecter_pdr_data(pdr1.data(), pdr1.size(), &decodedPdr);
+    EXPECT_EQ(PLDM_SUCCESS, rc);
+
+    EXPECT_EQ(PLDM_EFFECTER_DATA_SIZE_SINT32, decodedPdr.effecter_data_size);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.state_transition_interval);
+    EXPECT_FLOAT_EQ(1.0f, decodedPdr.transition_interval);
+    EXPECT_EQ(100000, decodedPdr.max_settable.value_s32);
+    EXPECT_EQ(-100000, decodedPdr.min_settable.value_s32);
+    EXPECT_EQ(PLDM_RANGE_FIELD_FORMAT_REAL32, decodedPdr.range_field_format);
+    EXPECT_EQ(0x1f, decodedPdr.range_field_support.byte);
+    EXPECT_FLOAT_EQ(0, decodedPdr.nominal_value.value_f32);
+    EXPECT_FLOAT_EQ(50.05f, decodedPdr.normal_max.value_f32);
+    EXPECT_FLOAT_EQ(-50.05f, decodedPdr.normal_min.value_f32);
+    EXPECT_FLOAT_EQ(300.003f, decodedPdr.rated_max.value_f32);
+    EXPECT_FLOAT_EQ(-300.003f, decodedPdr.rated_min.value_f32);
+}