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/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);
+}