pldmtool: Add GetSensorReading command

Added GetSensorReading command to get the current sensor
value and its state.

Tested results:
```
root@bmc:~# pldmtool platform getSensorReading -h
get the numeric sensor reading
Usage: pldmtool platform GetSensorReading [OPTIONS]

Options:
  -h,--help                   Print this help message and exit
  -m,--mctp_eid UINT          MCTP endpoint ID
  -v,--verbose
  -n,--retry-count UINT       Number of retry when PLDM request
message is failed
  -i,--sensor_id UINT REQUIRED
                              Sensor ID that is used to identify
and access the sensor
  -r,--rearm UINT REQUIRED    Manually re-arm EventState after
responding to this request
root@bmc:~# pldmtool platform getSensorReading -m9 -r0 -i300
{
    "sensorDataSize": "uint8",
    "sensorOperationalState": "Sensor Enabled",
    "sensorEventMessageEnable": "Sensor Events Enabled",
    "presentState": "Sensor Normal",
    "previousState": "Sensor Unknown",
    "eventState": "Sensor Normal",
    "presentReading": 38
}
```

Change-Id: I83a111eef73ee20a06c699405a9cdf1f848dd66a
Signed-off-by: Ruslan Magomedov <velochimc@mail.ru>
diff --git a/pldmtool/pldm_platform_cmd.cpp b/pldmtool/pldm_platform_cmd.cpp
index 46d0744..6a75cf8 100644
--- a/pldmtool/pldm_platform_cmd.cpp
+++ b/pldmtool/pldm_platform_cmd.cpp
@@ -1643,6 +1643,163 @@
     uint8_t sensorRearm;
 };
 
+class GetSensorReading : public CommandInterface
+{
+  public:
+    ~GetSensorReading() = default;
+    GetSensorReading() = delete;
+    GetSensorReading(const GetSensorReading&) = delete;
+    GetSensorReading(GetSensorReading&&) = default;
+    GetSensorReading& operator=(const GetSensorReading&) = delete;
+    GetSensorReading& operator=(GetSensorReading&&) = delete;
+
+    explicit GetSensorReading(const char* type, const char* name,
+                              CLI::App* app) :
+        CommandInterface(type, name, app)
+    {
+        app->add_option(
+               "-i, --sensor_id", sensorId,
+               "Sensor ID that is used to identify and access the sensor")
+            ->required();
+        app->add_option("-r, --rearm", rearm,
+                        "Manually re-arm EventState after "
+                        "responding to this request")
+            ->required();
+    }
+
+    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+    {
+        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+                                        PLDM_GET_SENSOR_READING_REQ_BYTES);
+        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+        auto rc = encode_get_sensor_reading_req(instanceId, sensorId, rearm,
+                                                request);
+
+        return {rc, requestMsg};
+    }
+
+    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
+    {
+        uint8_t completionCode = 0;
+        uint8_t sensorDataSize = 0;
+        uint8_t sensorOperationalState = 0;
+        uint8_t sensorEventMessageEnable = 0;
+        uint8_t presentState = 0;
+        uint8_t previousState = 0;
+        uint8_t eventState = 0;
+        std::array<uint8_t, sizeof(uint32_t)>
+            presentReading{}; // maximum size for the present Value is uint32
+                              // according to spec DSP0248
+
+        auto rc = decode_get_sensor_reading_resp(
+            responsePtr, payloadLength, &completionCode, &sensorDataSize,
+            &sensorOperationalState, &sensorEventMessageEnable, &presentState,
+            &previousState, &eventState, presentReading.data());
+
+        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+        {
+            std::cerr << "Response Message Error: "
+                      << "rc=" << rc << ",cc=" << (int)completionCode
+                      << std::endl;
+            return;
+        }
+
+        ordered_json output;
+        output["sensorDataSize"] = getSensorState(sensorDataSize,
+                                                  &sensorDataSz);
+        output["sensorOperationalState"] =
+            getSensorState(sensorOperationalState, &sensorOpState);
+        output["sensorEventMessageEnable"] =
+            getSensorState(sensorEventMessageEnable, &sensorEventMsgEnable);
+        output["presentState"] = getSensorState(presentState, &sensorPresState);
+        output["previousState"] = getSensorState(previousState,
+                                                 &sensorPresState);
+        output["eventState"] = getSensorState(eventState, &sensorPresState);
+
+        switch (sensorDataSize)
+        {
+            case PLDM_SENSOR_DATA_SIZE_UINT8:
+            {
+                output["presentReading"] =
+                    *(reinterpret_cast<uint8_t*>(presentReading.data()));
+                break;
+            }
+            case PLDM_SENSOR_DATA_SIZE_SINT8:
+            {
+                output["presentReading"] =
+                    *(reinterpret_cast<int8_t*>(presentReading.data()));
+                break;
+            }
+            case PLDM_SENSOR_DATA_SIZE_UINT16:
+            {
+                output["presentReading"] =
+                    *(reinterpret_cast<uint16_t*>(presentReading.data()));
+                break;
+            }
+            case PLDM_SENSOR_DATA_SIZE_SINT16:
+            {
+                output["presentReading"] =
+                    *(reinterpret_cast<int16_t*>(presentReading.data()));
+                break;
+            }
+            case PLDM_SENSOR_DATA_SIZE_UINT32:
+            {
+                output["presentReading"] =
+                    *(reinterpret_cast<uint32_t*>(presentReading.data()));
+                break;
+            }
+            case PLDM_SENSOR_DATA_SIZE_SINT32:
+            {
+                output["presentReading"] =
+                    *(reinterpret_cast<int32_t*>(presentReading.data()));
+                break;
+            }
+            default:
+            {
+                std::cerr << "Unknown Sensor Data Size : "
+                          << static_cast<int>(sensorDataSize) << std::endl;
+                break;
+            }
+        }
+
+        pldmtool::helper::DisplayInJson(output);
+    }
+
+  private:
+    uint16_t sensorId;
+    uint8_t rearm;
+
+    const std::map<uint8_t, std::string> sensorDataSz = {
+        {PLDM_SENSOR_DATA_SIZE_UINT8, "uint8"},
+        {PLDM_SENSOR_DATA_SIZE_SINT8, "uint8"},
+        {PLDM_SENSOR_DATA_SIZE_UINT16, "uint16"},
+        {PLDM_SENSOR_DATA_SIZE_SINT16, "uint16"},
+        {PLDM_SENSOR_DATA_SIZE_UINT32, "uint32"},
+        {PLDM_SENSOR_DATA_SIZE_SINT32, "uint32"}};
+
+    static inline const std::map<uint8_t, std::string> sensorEventMsgEnable{
+        {PLDM_NO_EVENT_GENERATION, "Sensor No Event Generation"},
+        {PLDM_EVENTS_DISABLED, "Sensor Events Disabled"},
+        {PLDM_EVENTS_ENABLED, "Sensor Events Enabled"},
+        {PLDM_OP_EVENTS_ONLY_ENABLED, "Sensor Op Events Only Enabled"},
+        {PLDM_STATE_EVENTS_ONLY_ENABLED, "Sensor State Events Only Enabled"}};
+
+    std::string getSensorState(uint8_t state,
+                               const std::map<uint8_t, std::string>* cont)
+    {
+        auto typeString = std::to_string(state);
+        try
+        {
+            return cont->at(state);
+        }
+        catch (const std::out_of_range& e)
+        {
+            return typeString;
+        }
+    }
+};
+
 class GetNumericEffecterValue : public CommandInterface
 {
   public:
@@ -1825,6 +1982,11 @@
         "GetNumericEffecterValue", "get the numeric effecter value");
     commands.push_back(std::make_unique<GetNumericEffecterValue>(
         "platform", "getNumericEffecterValue", getNumericEffecterValue));
+
+    auto getSensorReading = platform->add_subcommand(
+        "GetSensorReading", "get the numeric sensor reading");
+    commands.push_back(std::make_unique<GetSensorReading>(
+        "platform", "getSensorReading", getSensorReading));
 }
 
 void parseGetPDROption()