usb-dbg: Support sensor out of threshold message present

Description:
 - Modified sensors config for greatlakes platform those currently supported.
 - Support OCP debug card sensor frame threshold message shown when sensor value is out of threshold.
   e.g “P0_temp XXC/UCR”
 - Support OCP debug card screen blink and invert the color if the sensor out of threshold.

Test Case:
Sensor threshold message should be shown on debug card when the sensor value is out of threshold.

Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
Change-Id: I894b50bee33ad84abc07c5aa086fe1b798b7079b
diff --git a/configs/greatlakes/cri_sensors.json b/configs/greatlakes/cri_sensors.json
index a40615b..de9a85e 100644
--- a/configs/greatlakes/cri_sensors.json
+++ b/configs/greatlakes/cri_sensors.json
@@ -1,68 +1,107 @@
 {
-    "_HSC_Temp": {
-        "short_name": "MB_HSC_TEMP_C:"
+    "BB_INLET_TEMP_C": {
+        "short_name": "BB_INLET_TEMP_C:"
     },
-    "_MB_Inlet_Temp": {
-        "short_name": "MB_INLET_TEMP_C:"
+    "BB_OUTLET_TEMP_C": {
+        "short_name": "BB_OUTLET_TEMP_C:"
     },
-    "_VCCIN_SPS_Temp": {
-        "short_name": "MB_VR_VCCIN_TEMP_C:"
+    "BB_HSC_TEMP_C": {
+        "short_name": "BB_HSC_TEMP_C:"
     },
-    "_VCCIN_VR_Pout": {
-        "short_name": "MB_VR_VCCIN_PWR_W:"
+    "NIC_TEMP_C": {
+        "short_name": "NIC_TEMP_C:"
     },
-    "_CPU_PWR": {
-        "short_name": "MB_SOC_PACKAGE_PWR_W:"
+    "BB_P5V_VOLT_V": {
+        "short_name": "BB_P5V_VOLT_V:"
     },
-    "_EHV_VR_Pout": {
-        "short_name": "MB_VR_EHV_PWR_W:"
+    "BB_P12V_VOLT_V": {
+        "short_name": "BB_P12V_VOLT_V:"
     },
-    "_FAON_VR_Pout": {
-        "short_name": "MB_VR_FAON_PWR_W:"
+    "BB_P3V3_STBY_VOLT_V": {
+        "short_name": "BB_P3V3_STBY_VOLT_V:"
     },
-    "_FIVRA_VR_Pout": {
-        "short_name": "MB_VR_FIVRA_PWR_W:"
+    "BB_P2V5_STBY_VOLT_V": {
+        "short_name": "BB_P2V5_STBY_VOLT_V:"
     },
-    "_VCCD_VR_Pout": {
-        "short_name": "MB_VR_VCCD_PWR_W:"
+    "BB_ADC_P5V_USB_VOLT_V": {
+        "short_name": "BB_ADC_P5V_USB_VOLT_V:"
     },
-    "_HSC_Input_Pwr": {
-        "short_name": "MB_HSC_INPUT_PWR_W:"
+    "BB_P1V8_STBY_VOLT_V": {
+        "short_name": "BB_P1V8_STBY_VOLT_V:"
     },
-    "_DIMMA_Temp": {
-        "short_name": "MB_DIMMA0_TEMP_C:"
+    "BB_P1V2_STBY_VOLT_V": {
+        "short_name": "BB_P1V2_STBY_VOLT_V:"
     },
-    "_DIMMC_Temp": {
-        "short_name": "MB_DIMMA2_TEMP_C:"
+    "BB_ADC_P1V0_STBY_VOLT_V": {
+        "short_name": "BB_ADC_P1V0_STBY_VOLT_V:"
     },
-    "_DIMMD_Temp": {
-        "short_name": "MB_DIMMA3_TEMP_C:"
+    "BB_ADC_P0V6_STBY_VOLT_V": {
+        "short_name": "BB_ADC_P0V6_STBY_VOLT_V:"
     },
-    "_DIMME_Temp": {
-        "short_name": "MB_DIMMA4_TEMP_C:"
+    "BB_ADC_P3V3_RGM_STBY_VOLT_V": {
+        "short_name": "BB_ADC_P3V3_RGM_STBY_VOLT_V:"
     },
-    "_DIMMG_Temp": {
-        "short_name": "MB_DIMMA6_TEMP_C:"
+    "BB_ADC_P3V3_NIC_VOLT_V": {
+        "short_name": "BB_ADC_P3V3_NIC_VOLT_V:"
     },
-    "_DIMMH_Temp": {
-        "short_name": "MB_DIMMA7_TEMP_C:"
+    "BB_MEDUSA_INPUT_VOLT_V": {
+        "short_name": "BB_MEDUSA_INPUT_VOLT_V:"
     },
-    "_SOC_CPU_Temp": {
-        "short_name": "MB_SOC_CPU_TEMP_C:"
+    "BB_MEDUSA_OUTPUT_VOLT_V": {
+        "short_name": "BB_MEDUSA_OUTPUT_VOLT_V:"
     },
-    "_FIO_Temp": {
-        "short_name": "FIO_FRONT_TEMP_C:"
+    "BB_HSC_INPUT_VOLT_V": {
+        "short_name": "BB_HSC_INPUT_VOLT_V:"
     },
-    "_VCCD_VR_Vol": {
-        "short_name": "MB_VR_VCCD_VOLT_V:"
+    "BB_ADC_NIC_P12V_VOLT_V": {
+        "short_name": "BB_ADC_NIC_P12V_VOLT_V:"
     },
-    "_VCCIN_VR_Vol": {
-        "short_name": "MB_VR_VCCIN_VOLT_V:"
+    "BB_MEDUSA_CURR_A": {
+        "short_name": "BB_MEDUSA_CURR_A:"
     },
-    "_EHV_VR_Vol": {
-        "short_name": "MB_VR_EHV_VOLT_V:"
+    "BB_HSC_OUTPUT_CURR_A": {
+        "short_name": "BB_HSC_OUTPUT_CURR_A:"
     },
-    "_HSC_Input_Vol": {
-        "short_name": "MB_HSC_INPUT_VOLT_V:"
+    "BB_ADC_FAN_OUTPUT_CURR_A": {
+        "short_name": "BB_ADC_FAN_OUTPUT_CURR_A:"
+    },
+    "BB_ADC_NIC_OUTPUT_CURR_A": {
+        "short_name": "BB_ADC_NIC_OUTPUT_CURR_A:"
+    },
+    "BB_MEDUSA_PWR_W": {
+        "short_name": "BB_MEDUSA_PWR_W:"
+    },
+    "BB_HSC_INPUT_PWR_W": {
+        "short_name": "BB_HSC_INPUT_PWR_W:"
+    },
+    "BB_NIC_PWR_W": {
+        "short_name": "BB_NIC_PWR_W:"
+    },
+    "BB_FAN0_TACH_RPM": {
+        "short_name": "BB_FAN0_TACH_RPM:"
+    },
+    "BB_FAN1_TACH_RPM": {
+        "short_name": "BB_FAN1_TACH_RPM:"
+    },
+    "BB_FAN2_TACH_RPM": {
+        "short_name": "BB_FAN2_TACH_RPM:"
+    },
+    "BB_FAN3_TACH_RPM": {
+        "short_name": "BB_FAN3_TACH_RPM:"
+    },
+    "BB_HSC_PEAK_OUTPUT_CURR_A": {
+        "short_name": "BB_HSC_PEAK_OUTPUT_CURR_A:"
+    },
+    "BB_HSC_PEAK_INPUT_PWR_W": {
+        "short_name": "BB_HSC_PEAK_INPUT_PWR_W:"
+    },
+    "BB_MEDUSA_VDELTA_VOLT_V": {
+        "short_name": "BB_MEDUSA_VDELTA_VOLT_V:"
+    },
+    "BB_CPU_PDB_VDELTA_VOLT_V": {
+        "short_name": "BB_CPU_PDB_VDELTA_VOLT_V:"
+    },
+    "BB_FAN_PWR_W": {
+        "short_name": "BB_FAN_PWR_W:"
     }
 }
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
index 6cc51e5..1b69e68 100644
--- a/src/storagecommands.cpp
+++ b/src/storagecommands.cpp
@@ -25,6 +25,7 @@
 #include <sdbusplus/timer.hpp>
 #include <sensorutils.hpp>
 #include <storagecommands.hpp>
+#include <unordered_map>
 
 #include <iostream>
 
@@ -75,6 +76,47 @@
 
 static sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection());
 
+using InterfaceName = std::string;
+using PropertyName = std::string;
+using ThresholdStr = std::string;
+
+enum class AlarmType
+{
+    low,
+    high
+};
+
+struct Property
+{
+    PropertyName name;
+    ThresholdStr threshold;
+};
+
+const std::vector<InterfaceName> thresholdCheckedOrder{
+    "xyz.openbmc_project.Sensor.Threshold.HardShutdown",
+    "xyz.openbmc_project.Sensor.Threshold.SoftShutdown",
+    "xyz.openbmc_project.Sensor.Threshold.Critical",
+    "xyz.openbmc_project.Sensor.Threshold.Warning"};
+
+const std::unordered_map<std::string, std::map<AlarmType, Property>>
+    alarmProperties{
+        {"xyz.openbmc_project.Sensor.Threshold.HardShutdown",
+         {{AlarmType::low, Property{"HardShutdownAlarmLow", "LNR"}},
+          {AlarmType::high, Property{"HardShutdownAlarmHigh", "UNR"}}}},
+
+        {"xyz.openbmc_project.Sensor.Threshold.SoftShutdown",
+         {{AlarmType::low, Property{"SoftShutdownAlarmLow", "LNR"}},
+          {AlarmType::high, Property{"SoftShutdownAlarmHigh", "UNR"}}}},
+
+        {"xyz.openbmc_project.Sensor.Threshold.Critical",
+         {{AlarmType::low, Property{"CriticalAlarmLow", "LCR"}},
+          {AlarmType::high, Property{"CriticalAlarmHigh", "UCR"}}}},
+
+        {"xyz.openbmc_project.Sensor.Threshold.Warning",
+         {{AlarmType::low, Property{"WarningAlarmLow", "LNC"}},
+          {AlarmType::high, Property{"WarningAlarmHigh", "UNC"}}}},
+    };
+
 static bool getSensorMap(std::string sensorConnection, std::string sensorPath,
                          SensorMap& sensorMap)
 {
@@ -821,6 +863,73 @@
     return -1;
 }
 
+int getSensorThreshold(std::string& name, std::string& thresholdStr)
+{
+    std::string connection;
+    std::string path;
+    int ret = -1;
+    thresholdStr = "";
+
+    ret = getSensorConnectionByName(name, connection, path);
+    if (ret < 0)
+    {
+        return ret;
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return ret;
+    }
+
+    // Iterate threshold interfaces with priority order
+    for (auto& interface : thresholdCheckedOrder)
+    {
+        auto interfaceProperty = alarmProperties.find(interface);
+        if (interfaceProperty == alarmProperties.end())
+        {
+            continue;
+        }
+
+        auto propertyValue = interfaceProperty->second;
+
+        // Checks threshold properties value in sensorMap
+        auto thresholdInterfaceSensorMap = sensorMap.find(interface);
+
+        // Ignore if interface not set
+        if (thresholdInterfaceSensorMap == sensorMap.end())
+        {
+            continue;
+        }
+
+        auto& thresholdMap = thresholdInterfaceSensorMap->second;
+
+        auto& propertyAlarmHigh = propertyValue.at(AlarmType::high);
+        auto alarmHigh = thresholdMap.find(propertyAlarmHigh.name);
+        if (alarmHigh != thresholdMap.end())
+        {
+            if (std::get<bool>(alarmHigh->second))
+            {
+                thresholdStr = propertyAlarmHigh.threshold;
+                break;
+            }
+        }
+
+        auto& propertyAlarmLow = propertyValue.at(AlarmType::low);
+        auto alarmLow = thresholdMap.find(propertyAlarmLow.name);
+        if (alarmLow != thresholdMap.end())
+        {
+            if (std::get<bool>(alarmLow->second))
+            {
+                thresholdStr = propertyAlarmLow.threshold;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
 int getSensorValue(std::string& name, double& val)
 {
     std::string connection;
diff --git a/src/usb-dbg.cpp b/src/usb-dbg.cpp
index a97a998..751d78d 100644
--- a/src/usb-dbg.cpp
+++ b/src/usb-dbg.cpp
@@ -40,6 +40,7 @@
 {
 int getSensorValue(std::string&, double&);
 int getSensorUnit(std::string&, std::string&);
+int getSensorThreshold(std::string&, std::string&);
 } // namespace storage
 
 void getMaxHostPosition(size_t& maxPosition)
@@ -756,7 +757,28 @@
                 if (ipmi::storage::getSensorUnit(senName, unitStr) == 0)
                     senStr += unitStr;
 
-                frame_snr.append(senStr.c_str(), 0);
+                std::string thresholdStr;
+                int ret =
+                    ipmi::storage::getSensorThreshold(senName, thresholdStr);
+                if (ret < 0)
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "Error getting critical sensor threshold status",
+                        phosphor::logging::entry("CRI_SENSOR_NAME=%s",
+                                                 senName.c_str()));
+                    return -1;
+                }
+                if (thresholdStr.size() != 0)
+                {
+                    senStr += ("/" + thresholdStr);
+                    std::string senStrWithBlinkAndInvertColor =
+                        ESC_ALT + senStr + ESC_RST;
+                    frame_snr.append(senStrWithBlinkAndInvertColor.c_str(), 0);
+                }
+                else
+                {
+                    frame_snr.append(senStr.c_str(), 0);
+                }
             }
             else
             {