Decode APIs for sensorEvent class data

The decode_sensor_event_data API will perform the task of sensorEvent
class from eventData. This function would return the sensorID,
sensorEventClass and buffer containing sensorEventClass data of
sensorEventClass type.

The below listed three APIs will perform the task of decoding the
sensorEventClass data depending on the sensorEventClass type and
return appropriate data corresponding to the sensorEventClass type.

 - decode_sensor_op_data, sensorOpState sensorEventClass type.
 - decode_state_sensor_data, stateSensorState sensorEventClass type.
 - decode_numeric_sensor_data, numericSensorState sensorEventClass
   type.

Added corresponding Unit tests for each API.

Change-Id: I9cf82aeaddbdd23e70122a75c98dd15d55c22dc2
Signed-off-by: Zahed Hossain <zahzahed@in.ibm.com>
diff --git a/libpldm/platform.c b/libpldm/platform.c
index 45abf5a..48df1ad 100644
--- a/libpldm/platform.c
+++ b/libpldm/platform.c
@@ -609,3 +609,150 @@
 	}
 	return PLDM_SUCCESS;
 }
+
+int decode_sensor_event_data(const uint8_t *event_data,
+			     size_t event_data_length, uint16_t *sensor_id,
+			     uint8_t *sensor_event_class_type,
+			     size_t *event_class_data_offset)
+{
+	if (event_data == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (event_data_length < PLDM_SENSOR_EVENT_DATA_MIN_LENGTH) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	size_t event_class_data_length =
+	    event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
+
+	struct pldm_sensor_event_data *sensor_event_data =
+	    (struct pldm_sensor_event_data *)event_data;
+	*sensor_id = sensor_event_data->sensor_id;
+	*sensor_event_class_type = sensor_event_data->sensor_event_class_type;
+	if (sensor_event_data->sensor_event_class_type ==
+	    PLDM_SENSOR_OP_STATE) {
+		if (event_class_data_length !=
+		    PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+	} else if (sensor_event_data->sensor_event_class_type ==
+		   PLDM_STATE_SENSOR_STATE) {
+		if (event_class_data_length !=
+		    PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+	} else if (sensor_event_data->sensor_event_class_type ==
+		   PLDM_NUMERIC_SENSOR_STATE) {
+		if (event_class_data_length <
+			PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
+		    event_class_data_length >
+			PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+	} else {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	*event_class_data_offset =
+	    sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
+	return PLDM_SUCCESS;
+}
+
+int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
+			  uint8_t *present_op_state, uint8_t *previous_op_state)
+{
+	if (sensor_data == NULL || present_op_state == NULL ||
+	    previous_op_state == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (sensor_data_length !=
+	    PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_sensor_event_sensor_op_state *sensor_op_data =
+	    (struct pldm_sensor_event_sensor_op_state *)sensor_data;
+	*present_op_state = sensor_op_data->present_op_state;
+	*previous_op_state = sensor_op_data->previous_op_state;
+	return PLDM_SUCCESS;
+}
+
+int decode_state_sensor_data(const uint8_t *sensor_data,
+			     size_t sensor_data_length, uint8_t *sensor_offset,
+			     uint8_t *event_state,
+			     uint8_t *previous_event_state)
+{
+	if (sensor_data == NULL || sensor_offset == NULL ||
+	    event_state == NULL || previous_event_state == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (sensor_data_length !=
+	    PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_sensor_event_state_sensor_state *sensor_state_data =
+	    (struct pldm_sensor_event_state_sensor_state *)sensor_data;
+	*sensor_offset = sensor_state_data->sensor_offset;
+	*event_state = sensor_state_data->event_state;
+	*previous_event_state = sensor_state_data->previous_event_state;
+	return PLDM_SUCCESS;
+}
+
+int decode_numeric_sensor_data(const uint8_t *sensor_data,
+			       size_t sensor_data_length, uint8_t *event_state,
+			       uint8_t *previous_event_state,
+			       uint8_t *sensor_data_size,
+			       uint32_t *present_reading)
+{
+	if (sensor_data == NULL || sensor_data_size == NULL ||
+	    event_state == NULL || previous_event_state == NULL ||
+	    present_reading == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (sensor_data_length <
+		PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
+	    sensor_data_length >
+		PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+	struct pldm_sensor_event_numeric_sensor_state *numeric_sensor_data =
+	    (struct pldm_sensor_event_numeric_sensor_state *)sensor_data;
+	*event_state = numeric_sensor_data->event_state;
+	*previous_event_state = numeric_sensor_data->previous_event_state;
+	*sensor_data_size = numeric_sensor_data->sensor_data_size;
+	uint8_t *present_reading_ptr = numeric_sensor_data->present_reading;
+
+	switch (*sensor_data_size) {
+	case PLDM_SENSOR_DATA_SIZE_UINT8:
+	case PLDM_SENSOR_DATA_SIZE_SINT8:
+		if (sensor_data_length !=
+		    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		*present_reading = present_reading_ptr[0];
+		break;
+	case PLDM_SENSOR_DATA_SIZE_UINT16:
+	case PLDM_SENSOR_DATA_SIZE_SINT16:
+		if (sensor_data_length !=
+		    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		*present_reading = le16toh(present_reading_ptr[1] |
+					   (present_reading_ptr[0] << 8));
+		break;
+	case PLDM_SENSOR_DATA_SIZE_UINT32:
+	case PLDM_SENSOR_DATA_SIZE_SINT32:
+		if (sensor_data_length !=
+		    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH) {
+			return PLDM_ERROR_INVALID_LENGTH;
+		}
+		*present_reading = le32toh(present_reading_ptr[3] |
+					   (present_reading_ptr[2] << 8) |
+					   (present_reading_ptr[1] << 16) |
+					   (present_reading_ptr[0] << 24));
+		break;
+	default:
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	return PLDM_SUCCESS;
+}
diff --git a/libpldm/platform.h b/libpldm/platform.h
index 181fd3e..ba0854c 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -28,6 +28,16 @@
 #define PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES 3
 #define PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES 6
 
+/* Minumum length of senson event data */
+#define PLDM_SENSOR_EVENT_DATA_MIN_LENGTH 5
+#define PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH 2
+#define PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH 3
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH 4
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH 7
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH 4
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH 5
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH 7
+
 enum pldm_effecter_data_size {
 	PLDM_EFFECTER_DATA_SIZE_UINT8,
 	PLDM_EFFECTER_DATA_SIZE_SINT8,
@@ -141,6 +151,17 @@
 	FORMAT_IS_PDR_HANDLES
 };
 
+/** @brief PLDM NumericSensorStatePresentReading data type
+ */
+enum pldm_sensor_readings_data_type {
+	PLDM_SENSOR_DATA_SIZE_UINT8,
+	PLDM_SENSOR_DATA_SIZE_SINT8,
+	PLDM_SENSOR_DATA_SIZE_UINT16,
+	PLDM_SENSOR_DATA_SIZE_SINT16,
+	PLDM_SENSOR_DATA_SIZE_UINT32,
+	PLDM_SENSOR_DATA_SIZE_SINT32
+};
+
 /** @struct pldm_pdr_hdr
  *
  *  Structure representing PLDM common PDR header
@@ -738,6 +759,80 @@
 				       uint8_t completion_code, uint8_t status,
 				       struct pldm_msg *msg);
 
+/** @brief Decode sensorEventData response data
+ *
+ *  @param[in] event_data - event data from the response message
+ *  @param[in] event_data_length - length of the event data
+ *  @param[out] sensor_id -  sensorID value of the sensor
+ *  @param[out] sensor_event_class_type - Type of sensor event class
+ *  @param[out] event_class_data_offset - Offset where the event class data
+ * should be read from event data
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'event_data'
+ */
+int decode_sensor_event_data(const uint8_t *event_data,
+			     size_t event_data_length, uint16_t *sensor_id,
+			     uint8_t *sensor_event_class_type,
+			     size_t *event_class_data_offset);
+
+/** @brief Decode sensorOpState response data
+ *
+ *  @param[in] sensor_data - sensor_data for sensorEventClass = sensorOpState
+ *  @param[in] sensor_data_length - Length of sensor_data
+ *  @param[out] present_op_state - The sensorOperationalState value from the
+ * state change that triggered the event message
+ *  @param[out] previous_op_state - The sensorOperationalState value for the
+ * state from which the present state was entered
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'sensor_data'
+ */
+int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
+			  uint8_t *present_op_state,
+			  uint8_t *previous_op_state);
+
+/** @brief Decode stateSensorState response data
+ *
+ *  @param[in] sensor_data - sensor_data for sensorEventClass = stateSensorState
+ *  @param[in] sensor_data_length - Length of sensor_data
+ *  @param[out] sensor_offset - Identifies which state sensor within a composite
+ * state sensor the event is being returned for
+ *  @param[out] event_state - The event state value from the state change that
+ * triggered the event message
+ *  @param[out] previous_event_state - The event state value for the state from
+ * which the present event state was entered
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'sensor_data'
+ */
+int decode_state_sensor_data(const uint8_t *sensor_data,
+			     size_t sensor_data_length, uint8_t *sensor_offset,
+			     uint8_t *event_state,
+			     uint8_t *previous_event_state);
+
+/** @brief Decode numericSensorState response data
+ *
+ *  @param[in] sensor_data - sensor_data for sensorEventClass =
+ * numericSensorState
+ *  @param[in] sensor_data_length - Length of sensor_data
+ *  @param[out] event_state - The eventState value from the state change that
+ * triggered the event message
+ *  @param[out] previous_event_state - The eventState value for the state from
+ * which the present state was entered
+ *  @param[out] sensor_data_size - The bit width and format of reading and
+ * threshold values that the sensor returns
+ *  @param[out] present_reading - The present value indicated by the sensor
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'sensor_data'
+ */
+int decode_numeric_sensor_data(const uint8_t *sensor_data,
+			       size_t sensor_data_length, uint8_t *event_state,
+			       uint8_t *previous_event_state,
+			       uint8_t *sensor_data_size,
+			       uint32_t *present_reading);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libpldm/tests/libpldm_platform_test.cpp b/libpldm/tests/libpldm_platform_test.cpp
index 18f1062..1261d0b 100644
--- a/libpldm/tests/libpldm_platform_test.cpp
+++ b/libpldm/tests/libpldm_platform_test.cpp
@@ -854,3 +854,268 @@
     auto rc = encode_platform_event_message_resp(0, PLDM_SUCCESS, 1, NULL);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
 }
+
+TEST(PlatformEventMessage, testGoodSensorEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH +
+                            PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES>
+        eventDataArr{};
+    uint16_t sensorId = 0x1234;
+    uint8_t sensorEventClassType = PLDM_SENSOR_OP_STATE;
+
+    struct pldm_sensor_event_data* eventData =
+        (struct pldm_sensor_event_data*)eventDataArr.data();
+    eventData->sensor_id = sensorId;
+    eventData->sensor_event_class_type = sensorEventClassType;
+
+    size_t retSensorOpDataOffset;
+    uint16_t retSensorId = 0;
+    uint8_t retSensorEventClassType;
+    size_t sensorOpDataOffset = sizeof(sensorId) + sizeof(sensorEventClassType);
+    auto rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventData), eventDataArr.size(),
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retSensorId, sensorId);
+    EXPECT_EQ(retSensorEventClassType, sensorEventClassType);
+    EXPECT_EQ(retSensorOpDataOffset, sensorOpDataOffset);
+}
+
+TEST(PlatformEventMessage, testBadSensorEventDataDecodeRequest)
+{
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH +
+                            PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES>
+        eventDataArr{};
+
+    struct pldm_sensor_event_data* eventData =
+        (struct pldm_sensor_event_data*)eventDataArr.data();
+
+    size_t retSensorOpDataOffset;
+    uint16_t retSensorId = 0;
+    uint8_t retSensorEventClassType;
+    auto rc = decode_sensor_event_data(NULL, eventDataArr.size(), &retSensorId,
+                                       &retSensorEventClassType,
+                                       &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()),
+        eventDataArr.size() -
+            PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH,
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    eventData->sensor_event_class_type = PLDM_SENSOR_OP_STATE;
+
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()), eventDataArr.size(),
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    eventData->sensor_event_class_type = PLDM_STATE_SENSOR_STATE;
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()), eventDataArr.size(),
+        &retSensorId, &retSensorEventClassType, &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    eventData->sensor_event_class_type = PLDM_NUMERIC_SENSOR_STATE;
+    rc = decode_sensor_event_data(
+        reinterpret_cast<uint8_t*>(eventDataArr.data()),
+        eventDataArr.size() + 1, &retSensorId, &retSensorEventClassType,
+        &retSensorOpDataOffset);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
+
+TEST(PlatformEventMessage, testGoodSensorOpEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH>
+        eventDataArr{};
+
+    struct pldm_sensor_event_sensor_op_state* sensorData =
+        (struct pldm_sensor_event_sensor_op_state*)eventDataArr.data();
+    uint8_t presentState = PLDM_SENSOR_ENABLED;
+    uint8_t previousState = PLDM_SENSOR_INITIALIZING;
+    sensorData->present_op_state = presentState;
+    sensorData->previous_op_state = previousState;
+
+    uint8_t retPresentState;
+    uint8_t retPreviousState;
+    auto rc = decode_sensor_op_data(reinterpret_cast<uint8_t*>(sensorData),
+                                    eventDataArr.size(), &retPresentState,
+                                    &retPreviousState);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retPresentState, presentState);
+    EXPECT_EQ(retPreviousState, previousState);
+}
+
+TEST(PlatformEventMessage, testBadSensorOpEventDataDecodeRequest)
+{
+    uint8_t presentOpState;
+    uint8_t previousOpState;
+    size_t sensorDataLength = PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH;
+    auto rc = decode_sensor_op_data(NULL, sensorDataLength, &presentOpState,
+                                    &previousOpState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH>
+        sensorData{};
+    rc = decode_sensor_op_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                               sensorDataLength + 1, &presentOpState,
+                               &previousOpState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_sensor_op_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                               sensorDataLength, nullptr, &previousOpState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessage, testGoodSensorStateEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH>
+        eventDataArr{};
+
+    struct pldm_sensor_event_state_sensor_state* sensorData =
+        (struct pldm_sensor_event_state_sensor_state*)eventDataArr.data();
+    uint8_t sensorOffset = 0x02;
+    uint8_t eventState = PLDM_SENSOR_SHUTTINGDOWN;
+    uint8_t previousEventState = PLDM_SENSOR_INTEST;
+    sensorData->sensor_offset = sensorOffset;
+    sensorData->event_state = eventState;
+    sensorData->previous_event_state = previousEventState;
+
+    uint8_t retSensorOffset;
+    uint8_t retEventState;
+    uint8_t retPreviousState;
+    auto rc = decode_state_sensor_data(reinterpret_cast<uint8_t*>(sensorData),
+                                       eventDataArr.size(), &retSensorOffset,
+                                       &retEventState, &retPreviousState);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retSensorOffset, sensorOffset);
+    EXPECT_EQ(retEventState, eventState);
+    EXPECT_EQ(retPreviousState, previousEventState);
+}
+
+TEST(PlatformEventMessage, testBadStateSensorEventDataDecodeRequest)
+{
+    uint8_t sensorOffset;
+    uint8_t eventState;
+    uint8_t previousEventState;
+    size_t sensorDataLength = PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH;
+    auto rc = decode_state_sensor_data(NULL, sensorDataLength, &sensorOffset,
+                                       &eventState, &previousEventState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH>
+        sensorData{};
+    rc = decode_state_sensor_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                                  sensorDataLength - 1, &sensorOffset,
+                                  &eventState, &previousEventState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    rc = decode_state_sensor_data(reinterpret_cast<uint8_t*>(sensorData.data()),
+                                  sensorDataLength, &sensorOffset, nullptr,
+                                  &previousEventState);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(PlatformEventMessage, testGoodNumericSensorEventDataDecodeRequest)
+{
+    std::array<uint8_t, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH>
+        eventDataArr{};
+    struct pldm_sensor_event_numeric_sensor_state* sensorData =
+        (struct pldm_sensor_event_numeric_sensor_state*)eventDataArr.data();
+
+    size_t sensorDataLength =
+        PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH;
+    uint8_t eventState = PLDM_SENSOR_SHUTTINGDOWN;
+    uint8_t previousEventState = PLDM_SENSOR_INTEST;
+    uint8_t sensorDataSize = PLDM_SENSOR_DATA_SIZE_UINT32;
+    uint32_t presentReading = 305441741;
+    sensorData->event_state = eventState;
+    sensorData->previous_event_state = previousEventState;
+    sensorData->sensor_data_size = sensorDataSize;
+    sensorData->present_reading[3] =
+        static_cast<uint8_t>(htole32(presentReading) & (0x000000ff));
+    sensorData->present_reading[2] =
+        static_cast<uint8_t>((htole32(presentReading) & (0x0000ff00)) >> 8);
+    sensorData->present_reading[1] =
+        static_cast<uint8_t>((htole32(presentReading) & (0x00ff0000)) >> 16);
+    sensorData->present_reading[0] =
+        static_cast<uint8_t>((htole32(presentReading) & (0xff000000)) >> 24);
+
+    uint8_t retEventState;
+    uint8_t retPreviousEventState;
+    uint8_t retSensorDataSize;
+    uint32_t retPresentReading;
+
+    auto rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData), sensorDataLength,
+        &retEventState, &retPreviousEventState, &retSensorDataSize,
+        &retPresentReading);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventState, eventState);
+    EXPECT_EQ(retPreviousEventState, previousEventState);
+    EXPECT_EQ(retSensorDataSize, sensorDataSize);
+    EXPECT_EQ(retPresentReading, presentReading);
+
+    int16_t presentReadingNew = -31432;
+    sensorData->present_reading[1] =
+        static_cast<uint8_t>(htole16(presentReadingNew) & (0x000000ff));
+    sensorData->present_reading[0] =
+        static_cast<uint8_t>((htole16(presentReadingNew) & (0x0000ff00)) >> 8);
+    sensorDataSize = PLDM_SENSOR_DATA_SIZE_SINT16;
+    sensorData->sensor_data_size = sensorDataSize;
+    sensorDataLength = PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH;
+
+    rc = decode_numeric_sensor_data(reinterpret_cast<uint8_t*>(sensorData),
+                                    sensorDataLength, &retEventState,
+                                    &retPreviousEventState, &retSensorDataSize,
+                                    &retPresentReading);
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(retEventState, eventState);
+    EXPECT_EQ(retPreviousEventState, previousEventState);
+    EXPECT_EQ(retSensorDataSize, sensorDataSize);
+    EXPECT_EQ(static_cast<int16_t>(retPresentReading), presentReadingNew);
+}
+
+TEST(PlatformEventMessage, testBadNumericSensorEventDataDecodeRequest)
+{
+    uint8_t eventState;
+    uint8_t previousEventState;
+    uint8_t sensorDataSize;
+    uint32_t presentReading;
+    size_t sensorDataLength =
+        PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH;
+    auto rc = decode_numeric_sensor_data(NULL, sensorDataLength, &eventState,
+                                         &previousEventState, &sensorDataSize,
+                                         &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::array<uint8_t, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH>
+        sensorData{};
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength - 1,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    struct pldm_sensor_event_numeric_sensor_state* numericSensorData =
+        (struct pldm_sensor_event_numeric_sensor_state*)sensorData.data();
+    numericSensorData->sensor_data_size = PLDM_SENSOR_DATA_SIZE_UINT8;
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    numericSensorData->sensor_data_size = PLDM_SENSOR_DATA_SIZE_UINT16;
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    numericSensorData->sensor_data_size = PLDM_SENSOR_DATA_SIZE_UINT32;
+    rc = decode_numeric_sensor_data(
+        reinterpret_cast<uint8_t*>(sensorData.data()), sensorDataLength - 1,
+        &eventState, &previousEventState, &sensorDataSize, &presentReading);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}