tpm: Support TPM Sensor type in Get sensor reading command

Change-Id: Icf4a10d8f6e2b95dae3d7dcf789711c5a3a46a39
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 53eb6d6..ea0eac4 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -14,7 +14,6 @@
 #include "utils.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 
-
 extern int updateSensorRecordFromSSRAESC(const void *);
 extern sd_bus *bus;
 extern const ipmi::sensor::IdInfoMap sensors;
@@ -477,7 +476,6 @@
     sd_bus_message *reply = NULL;
     int reading = 0;
 
-
     printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum);
 
     r = find_openbmc_path(reqptr->sennum, &a);
@@ -574,14 +572,82 @@
             rc = IPMI_CC_OK;
             *data_len=sizeof(sensorreadingresp_t);
             break;
+        case IPMI_SENSOR_TPM:
+        {
+            auto iter = sensors.find(reqptr->sennum);
+            if (iter == sensors.end())
+            {
+                return IPMI_CC_SENSOR_INVALID;
+            }
 
+            auto& interfaceList = iter->second.propertyInterfaces;
+            if (interfaceList.empty())
+            {
+                log<level::ERR>("Interface List empty for the sensor",
+                        entry("SENSOR_NUMBER=%d", reqptr->sennum));
+                return IPMI_CC_UNSPECIFIED_ERROR;
+            }
+
+            /* For the TPM sensor there is no reading value and sensor scanning
+             * is disabled. This is a discrete sensor and only the
+             * corresponding state is asserted.
+             */
+            resp->value = 0;
+            resp->operation = 0;
+            resp->indication[0] = 0;
+            resp->indication[1] = 0;
+
+            try
+            {
+                for (const auto& interface : interfaceList)
+                {
+                    for (const auto& property : interface.second)
+                    {
+                        sdbusplus::bus::bus dbus{ipmid_get_sd_bus_connection()};
+
+                        auto service = ipmi::getService(
+                                       dbus,
+                                       interface.first,
+                                       iter->second.sensorPath);
+
+                        auto propValue = ipmi::getDbusProperty(
+                                dbus, service, iter->second.sensorPath,
+                                interface.first, property.first);
+
+                        auto tpmStatus = propValue.get<bool>();
+
+                        for (const auto& value : property.second)
+                        {
+                            if (tpmStatus == (value.second.assert).get<bool>())
+                            {
+                                /*
+                                 * The discrete sensors support upto 14 states.
+                                 * The assertion states for discrete sensors are
+                                 * stored in 2 bytes, 0-7 in Byte 4 of the
+                                 * response and 8-14 in Byte 5 of the response.
+                                 */
+                                 resp->indication[0] |= 1 << (value.first);
+                                 break;
+                            }
+                        }
+                    }
+                }
+
+                rc = IPMI_CC_OK;
+                *data_len = sizeof(sensorreadingresp_t);
+            }
+            catch (InternalFailure& e)
+            {
+                return IPMI_CC_UNSPECIFIED_ERROR;
+            }
+            break;
+        }
         default:
             *data_len=0;
             rc = IPMI_CC_SENSOR_INVALID;
             break;
     }
 
-
     reply = sd_bus_message_unref(reply);
 
     return rc;