libpldm: Implement encode/decode for GetNumericEffecterValue
The spec of GetNumericEffecterValue command refers to DSP0248_1.2.0:22.3
Change-Id: Ief5e00859d23c981611736b6ee257b182f0e6809
Signed-off-by: Jolie Ku <jolie_ku@wistron.com>
diff --git a/libpldm/platform.c b/libpldm/platform.c
index 48df1ad..5dd388e 100644
--- a/libpldm/platform.c
+++ b/libpldm/platform.c
@@ -756,3 +756,186 @@
}
return PLDM_SUCCESS;
}
+
+int encode_get_numeric_effecter_value_req(uint8_t instance_id,
+ uint16_t effecter_id,
+ struct pldm_msg *msg)
+{
+ struct pldm_header_info header = {0};
+ int rc = PLDM_SUCCESS;
+
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ struct pldm_get_numeric_effecter_value_req *request =
+ (struct pldm_get_numeric_effecter_value_req *)msg->payload;
+
+ header.msg_type = PLDM_REQUEST;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_PLATFORM;
+ header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
+
+ if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
+ return rc;
+ }
+
+ request->effecter_id = htole16(effecter_id);
+
+ return PLDM_SUCCESS;
+}
+
+int encode_get_numeric_effecter_value_resp(
+ uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
+ uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
+ struct pldm_msg *msg, size_t payload_length)
+{
+ struct pldm_header_info header = {0};
+ int rc = PLDM_SUCCESS;
+
+ if (msg == NULL || pending_value == NULL || present_value == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ header.msg_type = PLDM_RESPONSE;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_PLATFORM;
+ header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
+
+ if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
+ return rc;
+ }
+
+ struct pldm_get_numeric_effecter_value_resp *response =
+ (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
+
+ response->completion_code = completion_code;
+ response->effecter_data_size = effecter_data_size;
+ response->effecter_oper_state = effecter_oper_state;
+
+ if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
+ effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
+ if (payload_length !=
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ response->pending_and_present_values[0] = *pending_value;
+ response->pending_and_present_values[1] = *present_value;
+
+ } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
+ effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
+ if (payload_length !=
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ memcpy(response->pending_and_present_values, pending_value, 2);
+ memcpy(&response->pending_and_present_values[2], present_value,
+ 2);
+
+ } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
+ effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
+ if (payload_length !=
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ memcpy(response->pending_and_present_values, pending_value, 4);
+ memcpy(&response->pending_and_present_values[4], present_value,
+ 4);
+ }
+ return PLDM_SUCCESS;
+}
+
+int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
+ size_t payload_length,
+ uint16_t *effecter_id)
+{
+ if (msg == NULL || effecter_id == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ if (payload_length != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ struct pldm_get_numeric_effecter_value_req *request =
+ (struct pldm_get_numeric_effecter_value_req *)msg->payload;
+
+ *effecter_id = le16toh(request->effecter_id);
+
+ return PLDM_SUCCESS;
+}
+
+int decode_get_numeric_effecter_value_resp(
+ const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+ uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
+ uint8_t *pending_value, uint8_t *present_value)
+{
+ if (msg == NULL || effecter_data_size == NULL ||
+ effecter_oper_state == NULL || pending_value == NULL ||
+ present_value == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ *completion_code = msg->payload[0];
+ if (PLDM_SUCCESS != *completion_code) {
+ return PLDM_SUCCESS;
+ }
+
+ if (payload_length < PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ struct pldm_get_numeric_effecter_value_resp *response =
+ (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
+
+ *effecter_data_size = response->effecter_data_size;
+ *effecter_oper_state = response->effecter_oper_state;
+
+ if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
+ *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
+ if (payload_length !=
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ memcpy(pending_value, response->pending_and_present_values, 1);
+ memcpy(present_value, &response->pending_and_present_values[1],
+ 1);
+
+ } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
+ *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
+ if (payload_length !=
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ memcpy(pending_value, response->pending_and_present_values, 2);
+ memcpy(present_value, &response->pending_and_present_values[2],
+ 2);
+
+ } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
+ *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
+ if (payload_length !=
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ memcpy(pending_value, response->pending_and_present_values, 4);
+ memcpy(present_value, &response->pending_and_present_values[4],
+ 4);
+ }
+ return PLDM_SUCCESS;
+}
\ No newline at end of file
diff --git a/libpldm/platform.h b/libpldm/platform.h
index 82c2b28..0ee050a 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -14,6 +14,7 @@
/* Maximum size for request */
#define PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES 19
#define PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES 4
+#define PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES 2
/* Response lengths are inclusive of completion code */
#define PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES 1
#define PLDM_GET_STATE_SENSOR_READINGS_RESP_BYTES 34
@@ -24,6 +25,7 @@
#define PLDM_GET_PDR_REQ_BYTES 13
/* Minimum response length */
#define PLDM_GET_PDR_MIN_RESP_BYTES 12
+#define PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES 5
/* Minimum length for PLDM PlatformEventMessage request */
#define PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES 3
@@ -77,9 +79,22 @@
UPPERFATAL = 0x0a
};
+enum pldm_effecter_oper_state {
+ EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING,
+ EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
+ EFFECTER_OPER_STATE_DISABLED,
+ EFFECTER_OPER_STATE_UNAVAILABLE,
+ EFFECTER_OPER_STATE_STATUSUNKNOWN,
+ EFFECTER_OPER_STATE_FAILED,
+ EFFECTER_OPER_STATE_INITIALIZING,
+ EFFECTER_OPER_STATE_SHUTTINGDOWN,
+ EFFECTER_OPER_STATE_INTEST
+};
+
enum pldm_platform_commands {
PLDM_GET_STATE_SENSOR_READINGS = 0x21,
PLDM_SET_NUMERIC_EFFECTER_VALUE = 0x31,
+ PLDM_GET_NUMERIC_EFFECTER_VALUE = 0x32,
PLDM_SET_STATE_EFFECTER_STATES = 0x39,
PLDM_GET_PDR = 0x51,
PLDM_PLATFORM_EVENT_MESSAGE = 0x0A
@@ -398,6 +413,25 @@
uint32_t change_entry[1];
} __attribute__((packed));
+/** @struct pldm_get_numeric_effecter_value_req
+ *
+ * structure representing GetNumericEffecterValue request packet
+ */
+struct pldm_get_numeric_effecter_value_req {
+ uint16_t effecter_id;
+} __attribute__((packed));
+
+/** @struct pldm_get_numeric_effecter_value_resp
+ *
+ * structure representing GetNumericEffecterValue response packet
+ */
+struct pldm_get_numeric_effecter_value_resp {
+ uint8_t completion_code;
+ uint8_t effecter_data_size;
+ uint8_t effecter_oper_state;
+ uint8_t pending_and_present_values[1];
+} __attribute__((packed));
+
/* Responder */
/* SetNumericEffecterValue */
@@ -565,6 +599,44 @@
get_sensor_state_field *field,
struct pldm_msg *msg);
+/* GetNumericEffecterValue */
+
+/** @brief Decode GetNumericEffecterValue request data
+ *
+ * @param[in] msg - Request message
+ * @param[in] payload_length - Length of request message payload
+ * @param[out] effecter_id - used to identify and access the effecter
+ * @return pldm_completion_codes
+ */
+int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
+ size_t payload_length,
+ uint16_t *effecter_id);
+
+/** @brief Create a PLDM response message for GetNumericEffecterValue
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] completion_code - PLDM completion code
+ * @param[in] effecter_data_size - The bit width and format of the setting
+ * value for the effecter.
+ * value:{uint8,sint8,uint16,sint16,uint32,sint32}
+ * @param[in] effecter_oper_state - The state of the effecter itself
+ * @param[in] pending_value - The pending numeric value setting of the
+ * effecter. The effecterDataSize field indicates the number of
+ * bits used for this field
+ * @param[in] present_value - The present numeric value setting of the
+ * effecter. The effecterDataSize indicates the number of bits
+ * used for this field
+ * @param[out] msg - Message will be written to this
+ * @param[in] payload_length - Length of request message payload
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'msg.payload'
+ */
+int encode_get_numeric_effecter_value_resp(
+ uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
+ uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
+ struct pldm_msg *msg, size_t payload_length);
+
/* Requester */
/* GetPDR */
@@ -846,6 +918,43 @@
uint8_t *sensor_data_size,
uint32_t *present_reading);
+/* GetNumericEffecterValue */
+
+/** @brief Create a PLDM request message for GetNumericEffecterValue
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] effecter_id - used to identify and access the effecter
+ * @param[out] msg - Message will be written to this
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'msg.payload'
+ */
+int encode_get_numeric_effecter_value_req(uint8_t instance_id,
+ uint16_t effecter_id,
+ struct pldm_msg *msg);
+
+/** @brief Create a PLDM response message for GetNumericEffecterValue
+ *
+ * @param[in] msg - Request message
+ * @param[in] payload_length - Length of request message payload
+ * @param[out] completion_code - PLDM completion code
+ * @param[out] effecter_data_size - The bit width and format of the setting
+ * value for the effecter.
+ * value:{uint8,sint8,uint16,sint16,uint32,sint32}
+ * @param[out] effecter_oper_state - The state of the effecter itself
+ * @param[out] pending_value - The pending numeric value setting of the
+ * effecter. The effecterDataSize field indicates the number of
+ * bits used for this field
+ * @param[out] present_value - The present numeric value setting of the
+ * effecter. The effecterDataSize indicates the number of bits
+ * used for this field
+ * @return pldm_completion_codes
+ */
+int decode_get_numeric_effecter_value_resp(
+ const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+ uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
+ uint8_t *pending_value, uint8_t *present_value);
+
#ifdef __cplusplus
}
#endif
diff --git a/libpldm/tests/libpldm_platform_test.cpp b/libpldm/tests/libpldm_platform_test.cpp
index 1261d0b..548ab05 100644
--- a/libpldm/tests/libpldm_platform_test.cpp
+++ b/libpldm/tests/libpldm_platform_test.cpp
@@ -1119,3 +1119,245 @@
&eventState, &previousEventState, &sensorDataSize, &presentReading);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
+
+TEST(GetNumericEffecterValue, testGoodEncodeRequest)
+{
+ std::vector<uint8_t> requestMsg(hdrSize +
+ PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES);
+
+ uint16_t effecter_id = 0xAB01;
+
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ auto rc = encode_get_numeric_effecter_value_req(0, effecter_id, request);
+
+ struct pldm_get_numeric_effecter_value_req* req =
+ reinterpret_cast<struct pldm_get_numeric_effecter_value_req*>(
+ request->payload);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(effecter_id, le16toh(req->effecter_id));
+}
+
+TEST(GetNumericEffecterValue, testBadEncodeRequest)
+{
+ std::vector<uint8_t> requestMsg(
+ hdrSize + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES);
+
+ auto rc = encode_get_numeric_effecter_value_req(0, 0, nullptr);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetNumericEffecterValue, testGoodDecodeRequest)
+{
+ std::array<uint8_t, hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES>
+ requestMsg{};
+
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ struct pldm_get_numeric_effecter_value_req* req =
+ reinterpret_cast<struct pldm_get_numeric_effecter_value_req*>(
+ request->payload);
+
+ uint16_t effecter_id = 0x12AB;
+ req->effecter_id = htole16(effecter_id);
+
+ uint16_t reteffecter_id;
+
+ auto rc = decode_get_numeric_effecter_value_req(
+ request, requestMsg.size() - hdrSize, &reteffecter_id);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(effecter_id, reteffecter_id);
+}
+
+TEST(GetNumericEffecterValue, testBadDecodeRequest)
+{
+ std::array<uint8_t, hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES>
+ requestMsg{};
+
+ auto rc = decode_get_numeric_effecter_value_req(
+ nullptr, requestMsg.size() - hdrSize, nullptr);
+
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ struct pldm_set_numeric_effecter_value_req* req =
+ reinterpret_cast<struct pldm_set_numeric_effecter_value_req*>(
+ request->payload);
+
+ uint16_t effecter_id = 0x1A;
+ req->effecter_id = htole16(effecter_id);
+ uint16_t reteffecter_id;
+
+ rc = decode_get_numeric_effecter_value_req(
+ request, requestMsg.size() - hdrSize - 1, &reteffecter_id);
+
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetNumericEffecterValue, testGoodEncodeResponse)
+{
+ uint8_t completionCode = 0;
+ uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT32;
+ uint8_t effecter_operState = EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING;
+ uint32_t pendingValue = 0x12345678;
+ uint32_t presentValue = 0xABCDEF00;
+
+ std::array<uint8_t,
+ hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6>
+ responseMsg{};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+ uint32_t pendingValue_le = htole32(pendingValue);
+ uint32_t presentValue_le = htole32(presentValue);
+
+ auto rc = encode_get_numeric_effecter_value_resp(
+ 0, completionCode, effecter_dataSize, effecter_operState,
+ reinterpret_cast<uint8_t*>(&pendingValue_le),
+ reinterpret_cast<uint8_t*>(&presentValue_le), response,
+ responseMsg.size() - hdrSize);
+
+ struct pldm_get_numeric_effecter_value_resp* resp =
+ reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+ response->payload);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(effecter_dataSize, resp->effecter_data_size);
+ EXPECT_EQ(effecter_operState, resp->effecter_oper_state);
+ EXPECT_EQ(pendingValue, le32toh(*(reinterpret_cast<uint32_t*>(
+ &resp->pending_and_present_values[0]))));
+ EXPECT_EQ(presentValue, le32toh(*(reinterpret_cast<uint32_t*>(
+ &resp->pending_and_present_values[4]))));
+}
+
+TEST(GetNumericEffecterValue, testBadEncodeResponse)
+{
+ std::array<uint8_t,
+ hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2>
+ responseMsg{};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+ uint8_t pendingValue = 0x01;
+ uint8_t presentValue = 0x02;
+
+ auto rc = encode_get_numeric_effecter_value_resp(
+ 0, PLDM_SUCCESS, 0, 0, nullptr, nullptr, nullptr,
+ responseMsg.size() - hdrSize);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = encode_get_numeric_effecter_value_resp(
+ 0, PLDM_SUCCESS, 6, 9, reinterpret_cast<uint8_t*>(&pendingValue),
+ reinterpret_cast<uint8_t*>(&presentValue), response,
+ responseMsg.size() - hdrSize);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+ uint8_t effecter_operState = EFFECTER_OPER_STATE_FAILED;
+
+ rc = encode_get_numeric_effecter_value_resp(
+ 0, PLDM_SUCCESS, effecter_dataSize, effecter_operState,
+ reinterpret_cast<uint8_t*>(&pendingValue),
+ reinterpret_cast<uint8_t*>(&presentValue), response,
+ responseMsg.size() - hdrSize);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetNumericEffecterValue, testGoodDecodeResponse)
+{
+ std::array<uint8_t,
+ hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2>
+ responseMsg{};
+
+ uint8_t completionCode = 0;
+ uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT16;
+ uint8_t effecter_operState = EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING;
+ uint16_t pendingValue = 0x4321;
+ uint16_t presentValue = 0xDCBA;
+
+ uint8_t retcompletionCode;
+ uint8_t reteffecter_dataSize;
+ uint8_t reteffecter_operState;
+ uint8_t retpendingValue[2];
+ uint8_t retpresentValue[2];
+
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+ struct pldm_get_numeric_effecter_value_resp* resp =
+ reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+ response->payload);
+
+ resp->completion_code = completionCode;
+ resp->effecter_data_size = effecter_dataSize;
+ resp->effecter_oper_state = effecter_operState;
+
+ uint16_t pendingValue_le = htole16(pendingValue);
+ memcpy(resp->pending_and_present_values, &pendingValue_le,
+ sizeof(pendingValue_le));
+ uint16_t presentValue_le = htole16(presentValue);
+ memcpy(&resp->pending_and_present_values[2], &presentValue_le,
+ sizeof(presentValue_le));
+
+ auto rc = decode_get_numeric_effecter_value_resp(
+ response, responseMsg.size() - hdrSize, &retcompletionCode,
+ &reteffecter_dataSize, &reteffecter_operState, retpendingValue,
+ retpresentValue);
+
+ uint16_t retpending_value =
+ le16toh(*(reinterpret_cast<uint16_t*>(retpendingValue)));
+ uint16_t retpresent_value =
+ le16toh(*(reinterpret_cast<uint16_t*>(retpresentValue)));
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(completionCode, retcompletionCode);
+ EXPECT_EQ(effecter_dataSize, reteffecter_dataSize);
+ EXPECT_EQ(effecter_operState, reteffecter_operState);
+ EXPECT_EQ(pendingValue, retpending_value);
+ EXPECT_EQ(presentValue, retpresent_value);
+}
+
+TEST(GetNumericEffecterValue, testBadDecodeResponse)
+{
+ std::array<uint8_t,
+ hdrSize + PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6>
+ responseMsg{};
+
+ auto rc = decode_get_numeric_effecter_value_resp(
+ nullptr, responseMsg.size() - hdrSize, nullptr, nullptr, nullptr,
+ nullptr, nullptr);
+
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ uint8_t completionCode = 0;
+ uint8_t effecter_dataSize = PLDM_EFFECTER_DATA_SIZE_SINT16;
+ uint8_t effecter_operState = EFFECTER_OPER_STATE_DISABLED;
+ uint16_t pendingValue = 0x5678;
+ uint16_t presentValue = 0xCDEF;
+
+ uint8_t retcompletionCode;
+ uint8_t reteffecter_dataSize;
+ uint8_t reteffecter_operState;
+ uint8_t retpendingValue[2];
+ uint8_t retpresentValue[2];
+
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+ struct pldm_get_numeric_effecter_value_resp* resp =
+ reinterpret_cast<struct pldm_get_numeric_effecter_value_resp*>(
+ response->payload);
+
+ resp->completion_code = completionCode;
+ resp->effecter_data_size = effecter_dataSize;
+ resp->effecter_oper_state = effecter_operState;
+
+ uint16_t pendingValue_le = htole16(pendingValue);
+ memcpy(resp->pending_and_present_values, &pendingValue_le,
+ sizeof(pendingValue_le));
+ uint16_t presentValue_le = htole16(presentValue);
+ memcpy(&resp->pending_and_present_values[2], &presentValue_le,
+ sizeof(presentValue_le));
+
+ rc = decode_get_numeric_effecter_value_resp(
+ response, responseMsg.size() - hdrSize, &retcompletionCode,
+ &reteffecter_dataSize, &reteffecter_operState, retpendingValue,
+ retpresentValue);
+
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}