Add support for debug card critical sensors

List of critical sensors read from json file cri_sensors.json
and its name along with current values will be displayed on
debug card screen.

Tested: verified with lcd debug card screen.

Change-Id: I1c7968b1d57efa9bf5e4cf8c7396fbeecbfbfd3a
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d365f69..16f3ab7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -74,7 +74,7 @@
 target_link_libraries (zfboemcmds phosphor_logging)
 
 set (PACKAGE_DIR /usr/share/lcd-debug/)
-set (CONFIG_FILES post_desc.json gpio_desc.json)
+set (CONFIG_FILES post_desc.json gpio_desc.json cri_sensors.json)
 
 install (TARGETS zfboemcmds DESTINATION lib/ipmid-providers)
 install (FILES ${CONFIG_FILES} DESTINATION ${PACKAGE_DIR})
diff --git a/cri_sensors.json b/cri_sensors.json
new file mode 100644
index 0000000..bde25f2
--- /dev/null
+++ b/cri_sensors.json
@@ -0,0 +1,62 @@
+{
+	"DTS_CPU1":
+	{
+		"short_name": "P0_TEMP:"
+	},
+	"DTS_CPU2":
+	{
+		"short_name": "P1_TEMP:"
+	},
+	"MB_HSC_IN_POWER":
+	{
+		"short_name": "HSC_PWR:"
+	},
+	"MB_HSC_IN_VOLT":
+	{
+		"short_name": "HSC_VOL:"
+	},
+	"MB_FAN0_TACH":
+	{
+		"short_name": "Fan0:"
+	},
+	"MB_FAN1_TACH":
+	{
+		"short_name": "Fan1:"
+	},
+	"MB_INLET_REMOTE_TEMP":
+	{
+		"short_name": "Inlet_TEMP:"
+	},
+	"MB_VR_CPU0_VCCIN_Temperature":
+	{
+		"short_name": "P0_VR_TEMP:"
+	},
+	"MB_VR_CPU1_VCCIN_Temperature":
+	{
+		"short_name": "P1_VR_TEMP:"
+	},
+	"MB_VR_CPU0_VCCIN_Output_Power":
+	{
+		"short_name": "P0_VR_Pwr:"
+	},
+	"MB_VR_CPU1_VCCIN_Output_Power":
+	{
+		"short_name": "P1_VR_Pwr:"
+	},
+	"MB_CPU0_DIMM_GRPA_TEMP":
+	{
+		"short_name": "DIMMA012_TEMP:"
+	},
+	"MB_CPU0_DIMM_GRPB_TEMP":
+	{
+		"short_name": "DIMMA345_TEMP:"
+	},
+	"MB_CPU1_DIMM_GRPC_TEMP":
+	{
+		"short_name": "DIMMB012_TEMP:"
+	},
+	"MB_CPU1_DIMM_GRPD_TEMP":
+	{
+		"short_name": "DIMMB345_TEMP:"
+	}
+}
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
index d64ebf4..d38008e 100644
--- a/src/storagecommands.cpp
+++ b/src/storagecommands.cpp
@@ -810,6 +810,56 @@
     return IPMI_CC_OK;
 }
 
+static int getSensorConnectionByName(std::string &name, std::string &connection,
+                                     std::string &path)
+{
+    if (sensorTree.empty() && !getSensorSubtree(sensorTree))
+    {
+        return -1;
+    }
+
+    for (const auto &sensor : sensorTree)
+    {
+        path = sensor.first;
+        if (path.find(name) != std::string::npos)
+        {
+            connection = sensor.second.begin()->first;
+            return 0;
+        }
+    }
+    return -1;
+}
+
+int getSensorValue(std::string &name, double &val)
+{
+    std::string connection;
+    std::string path;
+    int ret = -1;
+
+    ret = getSensorConnectionByName(name, connection, path);
+    if (ret < 0)
+    {
+        return ret;
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return ret;
+    }
+    auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value");
+
+    if (sensorObject == sensorMap.end() ||
+        sensorObject->second.find("Value") == sensorObject->second.end())
+    {
+        return ret;
+    }
+    auto &valueVariant = sensorObject->second["Value"];
+    val = std::visit(VariantToDoubleVisitor(), valueVariant);
+
+    return 0;
+}
+
 void registerStorageFunctions()
 {
     // <READ FRU Data>
diff --git a/src/usb-dbg.cpp b/src/usb-dbg.cpp
index 6e3847f..dc6522e 100644
--- a/src/usb-dbg.cpp
+++ b/src/usb-dbg.cpp
@@ -22,6 +22,7 @@
 
 #include <fstream>
 #include <iostream>
+#include <sstream>
 #include <phosphor-logging/log.hpp>
 #include <appcommands.hpp>
 
@@ -30,6 +31,7 @@
 
 #define JSON_POST_DATA_FILE "/usr/share/lcd-debug/post_desc.json"
 #define JSON_GPIO_DATA_FILE "/usr/share/lcd-debug/gpio_desc.json"
+#define JSON_SENSOR_NAMES_FILE "/usr/share/lcd-debug/cri_sensors.json"
 
 #define ETH_INTF_NAME "eth0"
 
@@ -62,6 +64,12 @@
 ipmi_ret_t getNetworkData(uint8_t lan_param, char *data);
 int8_t getFruData(std::string &serial, std::string &name);
 
+/* Declare storage functions used here */
+namespace storage
+{
+int getSensorValue(std::string &, double &);
+}
+
 typedef struct _sensor_desc
 {
     char name[16];
@@ -586,7 +594,6 @@
     return -1;
 }
 
-/* Need to implement this */
 int plat_udbg_get_gpio_desc(uint8_t index, uint8_t *next, uint8_t *level,
                             uint8_t *def, uint8_t *length, uint8_t *buffer)
 {
@@ -750,13 +757,8 @@
 static int udbg_get_cri_sensor(uint8_t frame, uint8_t page, uint8_t *next,
                                uint8_t *count, uint8_t *buffer)
 {
-    char str[32], temp_val[16], temp_thresh[8], print_format[32];
-    int i, ret;
-    float fvalue;
-    sensor_desc_t *cri_sensor = NULL;
-    size_t sensor_count = 0;
-    uint8_t pos = plat_get_fru_sel();
-    uint8_t fru;
+    int ret;
+    double fvalue;
 
     if (page == 1)
     {
@@ -765,7 +767,54 @@
         // initialize and clear frame
         frame_snr.init(FRAME_BUFF_SIZE);
         snprintf(frame_snr.title, 32, "CriSensor");
-        frame_snr.append(str, 0);
+
+        nlohmann::json senObj;
+
+        /* Get critical sensor names stored in json file */
+        std::ifstream file(JSON_SENSOR_NAMES_FILE);
+        if (file)
+        {
+            file >> senObj;
+            file.close();
+        }
+        else
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Critical Sensor names file not found",
+                phosphor::logging::entry("CRI_SENSOR_NAMES_FILE=%s",
+                                         JSON_SENSOR_NAMES_FILE));
+            return -1;
+        }
+
+        /* Get sensors values for all critical sensors */
+        for (auto &j : senObj.items())
+        {
+            std::string senName = j.key();
+            auto val = j.value();
+
+            if (ipmi::storage::getSensorValue(senName, fvalue) == 0)
+            {
+                std::stringstream ss;
+                ss << fvalue;
+
+                std::string senStr;
+                if (val.find("short_name") != val.end())
+                    senStr = val["short_name"];
+                else
+                    senStr = senName;
+
+                senStr += ss.str();
+                frame_snr.append(senStr.c_str(), 0);
+            }
+            else
+            {
+                phosphor::logging::log<phosphor::logging::level::INFO>(
+                    "Critical sensor not found",
+                    phosphor::logging::entry("CRI_SENSOR_NAME=%s",
+                                             senName.c_str()));
+            }
+        }
+
     } // End of update frame
 
     if (page > frame_snr.pages)