libpldm: Implement encode/decode for GetSensorReading

The spec of GetSensorReading command refers to DSP0248_1.2.0:18.2

Change-Id: I3749efe77db6ff4f87f72a4c59d716522a4aba39
Signed-off-by: Jolie Ku <jolie_ku@wistron.com>
Signed-off-by: George Liu <liuxiwei@inspur.com>
diff --git a/libpldm/platform.c b/libpldm/platform.c
index 9ff6bc9..399f2ff 100644
--- a/libpldm/platform.c
+++ b/libpldm/platform.c
@@ -1080,3 +1080,192 @@
 
 	return PLDM_SUCCESS;
 }
+
+int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
+				  uint8_t rearm_event_state,
+				  struct pldm_msg *msg)
+{
+	struct pldm_header_info header = {0};
+	int rc = PLDM_SUCCESS;
+
+	header.msg_type = PLDM_REQUEST;
+	header.instance = instance_id;
+	header.pldm_type = PLDM_PLATFORM;
+	header.command = PLDM_GET_SENSOR_READING;
+
+	if (msg == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
+		return rc;
+	}
+
+	struct pldm_get_sensor_reading_req *request =
+	    (struct pldm_get_sensor_reading_req *)msg->payload;
+
+	request->sensor_id = htole16(sensor_id);
+	request->rearm_event_state = rearm_event_state;
+
+	return PLDM_SUCCESS;
+}
+
+int decode_get_sensor_reading_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
+    uint8_t *sensor_event_message_enable, uint8_t *present_state,
+    uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
+{
+	if (msg == NULL || completion_code == NULL ||
+	    sensor_data_size == NULL || sensor_operational_state == NULL ||
+	    sensor_event_message_enable == NULL || present_state == NULL ||
+	    previous_state == NULL || event_state == NULL ||
+	    present_reading == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	*completion_code = msg->payload[0];
+	if (PLDM_SUCCESS != *completion_code) {
+		return PLDM_SUCCESS;
+	}
+
+	if (payload_length < PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_get_sensor_reading_resp *response =
+	    (struct pldm_get_sensor_reading_resp *)msg->payload;
+
+	if (response->sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (response->sensor_data_size > *sensor_data_size) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	*sensor_data_size = response->sensor_data_size;
+	*sensor_operational_state = response->sensor_operational_state;
+	*sensor_event_message_enable = response->sensor_event_message_enable;
+	*present_state = response->present_state;
+	*previous_state = response->previous_state;
+	*event_state = response->event_state;
+
+	if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
+	    *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
+		if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		*present_reading = response->present_reading[0];
+
+	} else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
+		   *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
+		if (payload_length !=
+		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		memcpy(present_reading, response->present_reading, 2);
+		uint16_t *val = (uint16_t *)(present_reading);
+		*val = le16toh(*val);
+
+	} else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
+		   *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
+		if (payload_length !=
+		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		memcpy(present_reading, response->present_reading, 4);
+		uint32_t *val = (uint32_t *)(present_reading);
+		*val = le32toh(*val);
+	}
+
+	return PLDM_SUCCESS;
+}
+
+int encode_get_sensor_reading_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
+    uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
+    uint8_t present_state, uint8_t previous_state, uint8_t event_state,
+    uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
+{
+	struct pldm_header_info header = {0};
+	int rc = PLDM_SUCCESS;
+
+	if (msg == NULL || present_reading == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	header.msg_type = PLDM_RESPONSE;
+	header.instance = instance_id;
+	header.pldm_type = PLDM_PLATFORM;
+	header.command = PLDM_GET_SENSOR_READING;
+
+	if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
+		return rc;
+	}
+
+	struct pldm_get_sensor_reading_resp *response =
+	    (struct pldm_get_sensor_reading_resp *)msg->payload;
+
+	response->completion_code = completion_code;
+	response->sensor_data_size = sensor_data_size;
+	response->sensor_operational_state = sensor_operational_state;
+	response->sensor_event_message_enable = sensor_event_message_enable;
+	response->present_state = present_state;
+	response->previous_state = previous_state;
+	response->event_state = event_state;
+
+	if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
+	    sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
+		if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		response->present_reading[0] = *present_reading;
+
+	} else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
+		   sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
+		if (payload_length !=
+		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		uint16_t val = *(uint16_t *)present_reading;
+		val = htole16(val);
+		memcpy(response->present_reading, &val, 2);
+
+	} else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
+		   sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
+		if (payload_length !=
+		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		uint32_t val = *(uint32_t *)present_reading;
+		val = htole32(val);
+		memcpy(response->present_reading, &val, 4);
+	}
+
+	return PLDM_SUCCESS;
+}
+
+int decode_get_sensor_reading_req(const struct pldm_msg *msg,
+				  size_t payload_length, uint16_t *sensor_id,
+				  uint8_t *rearm_event_state)
+{
+	if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	if (payload_length != PLDM_GET_SENSOR_READING_REQ_BYTES) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_get_sensor_reading_req *request =
+	    (struct pldm_get_sensor_reading_req *)msg->payload;
+
+	*sensor_id = le16toh(request->sensor_id);
+	*rearm_event_state = request->rearm_event_state;
+
+	return PLDM_SUCCESS;
+}
diff --git a/libpldm/platform.h b/libpldm/platform.h
index b3b8eac..3fc8ab3 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -15,6 +15,7 @@
 #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
+#define PLDM_GET_SENSOR_READING_REQ_BYTES 4
 /* 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
@@ -26,6 +27,7 @@
 /* Minimum response length */
 #define PLDM_GET_PDR_MIN_RESP_BYTES 12
 #define PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES 5
+#define PLDM_GET_SENSOR_READING_MIN_RESP_BYTES 8
 
 /* Minimum length for PLDM PlatformEventMessage request */
 #define PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES 3
@@ -84,6 +86,14 @@
 	UPPERFATAL = 0x0a
 };
 
+enum pldm_sensor_event_message_enable {
+	PLDM_NO_EVENT_GENERATION,
+	PLDM_EVENTS_DISABLED,
+	PLDM_EVENTS_ENABLED,
+	PLDM_OP_EVENTS_ONLY_ENABLED,
+	PLDM_STATE_EVENTS_ONLY_ENABLED
+};
+
 enum pldm_effecter_oper_state {
 	EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING,
 	EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
@@ -97,6 +107,7 @@
 };
 
 enum pldm_platform_commands {
+	PLDM_GET_SENSOR_READING = 0x11,
 	PLDM_GET_STATE_SENSOR_READINGS = 0x21,
 	PLDM_SET_NUMERIC_EFFECTER_VALUE = 0x31,
 	PLDM_GET_NUMERIC_EFFECTER_VALUE = 0x32,
@@ -464,6 +475,30 @@
 	uint8_t pending_and_present_values[1];
 } __attribute__((packed));
 
+/** @struct pldm_get_sensor_reading_req
+ *
+ *  Structure representing PLDM get sensor reading request
+ */
+struct pldm_get_sensor_reading_req {
+	uint16_t sensor_id;
+	bool8_t rearm_event_state;
+} __attribute__((packed));
+
+/** @struct pldm_get_sensor_reading_resp
+ *
+ *  Structure representing PLDM get sensor reading response
+ */
+struct pldm_get_sensor_reading_resp {
+	uint8_t completion_code;
+	uint8_t sensor_data_size;
+	uint8_t sensor_operational_state;
+	uint8_t sensor_event_message_enable;
+	uint8_t present_state;
+	uint8_t previous_state;
+	uint8_t event_state;
+	uint8_t present_reading[1];
+} __attribute__((packed));
+
 /* Responder */
 
 /* SetNumericEffecterValue */
@@ -669,6 +704,51 @@
     uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
     struct pldm_msg *msg, size_t payload_length);
 
+/* GetSensorReading */
+
+/** @brief Decode GetSensorReading request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] sensor_id - A handle that is used to identify and access
+ *         the sensor
+ *  @param[out] rearm_event_state - true =  manually re-arm EventState after
+ *         responding to this request, false = no manual re-arm
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_sensor_reading_req(const struct pldm_msg *msg,
+				  size_t payload_length, uint16_t *sensor_id,
+				  bool8_t *rearm_event_state);
+
+/** @brief Encode GetSensorReading response data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] sensor_data_size - The bit width and format of reading and
+ *         threshold values
+ *  @param[out] sensor_operational_state - The state of the sensor itself
+ *  @param[out] sensor_event_message_enable - value: { noEventGeneration,
+ *         eventsDisabled, eventsEnabled, opEventsOnlyEnabled,
+ *         stateEventsOnlyEnabled }
+ *  @param[out] present_state - The most recently assessed state value monitored
+ *         by the sensor
+ *  @param[out] previous_state - The state that the presentState was entered
+ *         from
+ *  @param[out] event_state - Indicates which threshold crossing assertion
+ *         events have been detected
+ *  @param[out] present_reading - The present value indicated by the sensor
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ */
+
+int encode_get_sensor_reading_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
+    uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
+    uint8_t present_state, uint8_t previous_state, uint8_t event_state,
+    uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length);
+
 /* Requester */
 
 /* GetPDR */
@@ -1062,6 +1142,51 @@
     uint8_t *event_data_operation, uint8_t *number_of_change_entries,
     size_t *change_entry_data_offset);
 
+/* GetSensorReading */
+
+/** @brief Encode GetSensorReading request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] sensor_id - A handle that is used to identify and access the
+ *         sensor
+ *  @param[in] rearm_event_state - true =  manually re-arm EventState after
+ *         responding to this request, false = no manual re-arm
+ *  @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_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
+				  bool8_t rearm_event_state,
+				  struct pldm_msg *msg);
+
+/** @brief Decode GetSensorReading response data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] sensor_data_size - The bit width and format of reading and
+ *         threshold values
+ *  @param[out] sensor_operational_state - The state of the sensor itself
+ *  @param[out] sensor_event_message_enable - value: { noEventGeneration,
+ *         eventsDisabled, eventsEnabled, opEventsOnlyEnabled,
+ *         stateEventsOnlyEnabled }
+ *  @param[out] present_state - The most recently assessed state value monitored
+ *         by the sensor
+ *  @param[out] previous_state - The state that the presentState was entered
+ *         from
+ *  @param[out] event_state - Indicates which threshold crossing assertion
+ *         events have been detected
+ *  @param[out] present_reading - The present value indicated by the sensor
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_sensor_reading_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
+    uint8_t *sensor_event_message_enable, uint8_t *present_state,
+    uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libpldm/tests/libpldm_platform_test.cpp b/libpldm/tests/libpldm_platform_test.cpp
index f8b9bc7..5e21e48 100644
--- a/libpldm/tests/libpldm_platform_test.cpp
+++ b/libpldm/tests/libpldm_platform_test.cpp
@@ -1585,3 +1585,264 @@
         &eventDataOperation, &numberOfChangeEntries, &changeEntryDataOffset);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
 }
+
+TEST(GetSensorReading, testGoodEncodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t sensorId = 0x1234;
+    bool8_t rearmEventState = 0x01;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto rc =
+        encode_get_sensor_reading_req(0, sensorId, rearmEventState, request);
+
+    struct pldm_get_sensor_reading_req* req =
+        reinterpret_cast<struct pldm_get_sensor_reading_req*>(request->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(sensorId, le16toh(req->sensor_id));
+    EXPECT_EQ(rearmEventState, req->rearm_event_state);
+}
+
+TEST(GetSensorReading, testBadEncodeRequest)
+{
+    auto rc = encode_get_sensor_reading_req(0, 0, 0, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetSensorReading, testGoodDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_REQ_BYTES>
+        requestMsg{};
+
+    uint16_t sensorId = 0xABCD;
+    bool8_t rearmEventState = 0xA;
+
+    uint16_t retsensorId;
+    bool8_t retrearmEventState;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    struct pldm_get_sensor_reading_req* req =
+        reinterpret_cast<struct pldm_get_sensor_reading_req*>(request->payload);
+
+    req->sensor_id = htole16(sensorId);
+    req->rearm_event_state = rearmEventState;
+
+    auto rc =
+        decode_get_sensor_reading_req(request, requestMsg.size() - hdrSize,
+                                      &retsensorId, &retrearmEventState);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(sensorId, retsensorId);
+    EXPECT_EQ(rearmEventState, retrearmEventState);
+}
+
+TEST(GetSensorReading, testBadDecodeRequest)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_REQ_BYTES>
+        requestMsg{};
+
+    auto rc = decode_get_sensor_reading_req(
+        nullptr, requestMsg.size() - hdrSize, nullptr, nullptr);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint16_t sensorId = 0xABCD;
+    bool8_t rearmEventState = 0xA;
+
+    uint16_t retsensorId;
+    bool8_t retrearmEventState;
+
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    struct pldm_get_sensor_reading_req* req =
+        reinterpret_cast<struct pldm_get_sensor_reading_req*>(request->payload);
+
+    req->sensor_id = htole16(sensorId);
+    req->rearm_event_state = rearmEventState;
+
+    rc = decode_get_sensor_reading_req(request, requestMsg.size() - hdrSize - 1,
+                                       &retsensorId, &retrearmEventState);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetSensorReading, testGoodEncodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t completionCode = 0;
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+    uint8_t sensor_operationalState = PLDM_SENSOR_ENABLED;
+    uint8_t sensor_event_messageEnable = PLDM_NO_EVENT_GENERATION;
+    uint8_t presentState = NORMAL;
+    uint8_t previousState = WARNING;
+    uint8_t eventState = UPPERWARNING;
+    uint8_t presentReading = 0x21;
+
+    auto rc = encode_get_sensor_reading_resp(
+        0, completionCode, sensor_dataSize, sensor_operationalState,
+        sensor_event_messageEnable, presentState, previousState, eventState,
+        reinterpret_cast<uint8_t*>(&presentReading), response,
+        responseMsg.size() - hdrSize);
+
+    struct pldm_get_sensor_reading_resp* resp =
+        reinterpret_cast<struct pldm_get_sensor_reading_resp*>(
+            response->payload);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, resp->completion_code);
+    EXPECT_EQ(sensor_dataSize, resp->sensor_data_size);
+    EXPECT_EQ(sensor_operationalState, resp->sensor_operational_state);
+    EXPECT_EQ(sensor_event_messageEnable, resp->sensor_event_message_enable);
+    EXPECT_EQ(presentState, resp->present_state);
+    EXPECT_EQ(previousState, resp->previous_state);
+    EXPECT_EQ(eventState, resp->event_state);
+    EXPECT_EQ(presentReading,
+              *(reinterpret_cast<uint8_t*>(&resp->present_reading[0])));
+}
+
+TEST(GetSensorReading, testBadEncodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3>
+        responseMsg{};
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+    uint8_t presentReading = 0x1;
+
+    auto rc = encode_get_sensor_reading_resp(0, PLDM_SUCCESS, 0, 0, 0, 0, 0, 0,
+                                             nullptr, nullptr,
+                                             responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = encode_get_sensor_reading_resp(
+        0, PLDM_SUCCESS, 6, 1, 1, 1, 1, 1,
+        reinterpret_cast<uint8_t*>(&presentReading), response,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+
+    rc = encode_get_sensor_reading_resp(
+        0, PLDM_SUCCESS, sensor_dataSize, 1, 1, 1, 1, 1,
+        reinterpret_cast<uint8_t*>(&presentReading), response,
+        responseMsg.size() - hdrSize);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(GetSensorReading, testGoodDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3>
+        responseMsg{};
+
+    uint8_t completionCode = 0;
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT32;
+    uint8_t sensor_operationalState = PLDM_SENSOR_STATUSUNKOWN;
+    uint8_t sensor_event_messageEnable = PLDM_EVENTS_ENABLED;
+    uint8_t presentState = CRITICAL;
+    uint8_t previousState = UPPERCRITICAL;
+    uint8_t eventState = WARNING;
+    uint32_t presentReading = 0xABCDEF11;
+
+    uint8_t retcompletionCode;
+    uint8_t retsensor_dataSize = PLDM_SENSOR_DATA_SIZE_UINT32;
+    uint8_t retsensor_operationalState;
+    uint8_t retsensor_event_messageEnable;
+    uint8_t retpresentState;
+    uint8_t retpreviousState;
+    uint8_t reteventState;
+    uint8_t retpresentReading[4];
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_sensor_reading_resp* resp =
+        reinterpret_cast<struct pldm_get_sensor_reading_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->sensor_data_size = sensor_dataSize;
+    resp->sensor_operational_state = sensor_operationalState;
+    resp->sensor_event_message_enable = sensor_event_messageEnable;
+    resp->present_state = presentState;
+    resp->previous_state = previousState;
+    resp->event_state = eventState;
+
+    uint32_t presentReading_le = htole32(presentReading);
+    memcpy(resp->present_reading, &presentReading_le,
+           sizeof(presentReading_le));
+
+    auto rc = decode_get_sensor_reading_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &retsensor_dataSize, &retsensor_operationalState,
+        &retsensor_event_messageEnable, &retpresentState, &retpreviousState,
+        &reteventState, retpresentReading);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retcompletionCode);
+    EXPECT_EQ(sensor_dataSize, retsensor_dataSize);
+    EXPECT_EQ(sensor_operationalState, retsensor_operationalState);
+    EXPECT_EQ(sensor_event_messageEnable, retsensor_event_messageEnable);
+    EXPECT_EQ(presentState, retpresentState);
+    EXPECT_EQ(previousState, retpreviousState);
+    EXPECT_EQ(eventState, reteventState);
+    EXPECT_EQ(presentReading,
+              *(reinterpret_cast<uint32_t*>(retpresentReading)));
+}
+
+TEST(GetSensorReading, testBadDecodeResponse)
+{
+    std::array<uint8_t, hdrSize + PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1>
+        responseMsg{};
+
+    auto rc = decode_get_sensor_reading_resp(
+        nullptr, responseMsg.size() - hdrSize, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr, nullptr, nullptr);
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    uint8_t completionCode = 0;
+    uint8_t sensor_dataSize = PLDM_EFFECTER_DATA_SIZE_UINT8;
+    uint8_t sensor_operationalState = INTEST;
+    uint8_t sensor_event_messageEnable = PLDM_EVENTS_DISABLED;
+    uint8_t presentState = FATAL;
+    uint8_t previousState = UPPERFATAL;
+    uint8_t eventState = WARNING;
+    uint8_t presentReading = 0xA;
+
+    uint8_t retcompletionCode;
+    uint8_t retsensor_dataSize = PLDM_SENSOR_DATA_SIZE_SINT16;
+    uint8_t retsensor_operationalState;
+    uint8_t retsensor_event_messageEnable;
+    uint8_t retpresent_state;
+    uint8_t retprevious_state;
+    uint8_t retevent_state;
+    uint8_t retpresentReading;
+
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_get_sensor_reading_resp* resp =
+        reinterpret_cast<struct pldm_get_sensor_reading_resp*>(
+            response->payload);
+
+    resp->completion_code = completionCode;
+    resp->sensor_data_size = sensor_dataSize;
+    resp->sensor_operational_state = sensor_operationalState;
+    resp->sensor_event_message_enable = sensor_event_messageEnable;
+    resp->present_state = presentState;
+    resp->previous_state = previousState;
+    resp->event_state = eventState;
+    resp->present_reading[0] = presentReading;
+
+    rc = decode_get_sensor_reading_resp(
+        response, responseMsg.size() - hdrSize, &retcompletionCode,
+        &retsensor_dataSize, &retsensor_operationalState,
+        &retsensor_event_messageEnable, &retpresent_state, &retprevious_state,
+        &retevent_state, reinterpret_cast<uint8_t*>(&retpresentReading));
+
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}