Update getThreshold to new API

This command is broken out into a "getIPMIThresholds" function
and the actual handler so that the SDR can call the same code
to get thresholds into IPMI format. Doing this caused quite a
bit of rewrite so I updated it to the new API as well.

Tested: IPMI sensor list thresholds still worked.

Change-Id: If6f33574d61549ec0e70955f3d1867af8d698246
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/sensorcommands.hpp b/include/sensorcommands.hpp
index fdae725..5e78c64 100644
--- a/include/sensorcommands.hpp
+++ b/include/sensorcommands.hpp
@@ -73,7 +73,7 @@
 };
 #pragma pack(pop)
 
-enum class IPMIhresholdRespBits
+enum class IPMIThresholdRespBits
 {
     lowerNonCritical,
     lowerCritical,
@@ -169,4 +169,13 @@
 
     return 0;
 }
+
+struct IPMIThresholds
+{
+    std::optional<uint8_t> warningLow;
+    std::optional<uint8_t> warningHigh;
+    std::optional<uint8_t> criticalLow;
+    std::optional<uint8_t> criticalHigh;
+};
+
 } // namespace ipmi
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
index 02df84c..844eef8 100644
--- a/src/sensorcommands.cpp
+++ b/src/sensorcommands.cpp
@@ -562,40 +562,9 @@
     return IPMI_CC_OK;
 }
 
-ipmi_ret_t ipmiSenGetSensorThresholds(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                                      ipmi_request_t request,
-                                      ipmi_response_t response,
-                                      ipmi_data_len_t dataLen,
-                                      ipmi_context_t context)
+IPMIThresholds getIPMIThresholds(const SensorMap &sensorMap)
 {
-    if (*dataLen != 1)
-    {
-        *dataLen = 0;
-        return IPMI_CC_REQ_DATA_LEN_INVALID;
-    }
-    *dataLen = 0; // default to 0 in case of an error
-
-    uint8_t sensnum = *(static_cast<uint8_t *>(request));
-
-    std::string connection;
-    std::string path;
-
-    auto status = getSensorConnection(sensnum, connection, path);
-    if (status)
-    {
-        return status;
-    }
-
-    SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
-    {
-        return IPMI_CC_RESPONSE_ERROR;
-    }
-
-    // zero out response buff
-    auto responseClear = static_cast<uint8_t *>(response);
-    std::fill(responseClear, responseClear + sizeof(SensorThresholdResp), 0);
-
+    IPMIThresholds resp;
     auto warningInterface =
         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning");
     auto criticalInterface =
@@ -610,7 +579,7 @@
         {
             // should not have been able to find a sensor not implementing
             // the sensor object
-            return IPMI_CC_RESPONSE_ERROR;
+            throw std::runtime_error("Invalid sensor map");
         }
 
         double max;
@@ -625,11 +594,8 @@
 
         if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned))
         {
-            return IPMI_CC_RESPONSE_ERROR;
+            throw std::runtime_error("Invalid sensor atrributes");
         }
-
-        auto msgReply = static_cast<SensorThresholdResp *>(response);
-
         if (warningInterface != sensorMap.end())
         {
             auto &warningMap = warningInterface->second;
@@ -639,22 +605,17 @@
 
             if (warningHigh != warningMap.end())
             {
-                msgReply->readable |=
-                    1 << static_cast<int>(
-                        IPMIhresholdRespBits::upperNonCritical);
+
                 double value = variant_ns::visit(VariantToDoubleVisitor(),
                                                  warningHigh->second);
-                msgReply->uppernc = scaleIPMIValueFromDouble(
+                resp.warningHigh = scaleIPMIValueFromDouble(
                     value, mValue, rExp, bValue, bExp, bSigned);
             }
             if (warningLow != warningMap.end())
             {
-                msgReply->readable |=
-                    1 << static_cast<int>(
-                        IPMIhresholdRespBits::lowerNonCritical);
                 double value = variant_ns::visit(VariantToDoubleVisitor(),
                                                  warningLow->second);
-                msgReply->lowernc = scaleIPMIValueFromDouble(
+                resp.warningLow = scaleIPMIValueFromDouble(
                     value, mValue, rExp, bValue, bExp, bSigned);
             }
         }
@@ -667,27 +628,94 @@
 
             if (criticalHigh != criticalMap.end())
             {
-                msgReply->readable |=
-                    1 << static_cast<int>(IPMIhresholdRespBits::upperCritical);
                 double value = variant_ns::visit(VariantToDoubleVisitor(),
                                                  criticalHigh->second);
-                msgReply->uppercritical = scaleIPMIValueFromDouble(
+                resp.criticalHigh = scaleIPMIValueFromDouble(
                     value, mValue, rExp, bValue, bExp, bSigned);
             }
             if (criticalLow != criticalMap.end())
             {
-                msgReply->readable |=
-                    1 << static_cast<int>(IPMIhresholdRespBits::lowerCritical);
                 double value = variant_ns::visit(VariantToDoubleVisitor(),
                                                  criticalLow->second);
-                msgReply->lowercritical = scaleIPMIValueFromDouble(
+                resp.criticalLow = scaleIPMIValueFromDouble(
                     value, mValue, rExp, bValue, bExp, bSigned);
             }
         }
     }
+    return resp;
+}
 
-    *dataLen = sizeof(SensorThresholdResp);
-    return IPMI_CC_OK;
+ipmi::RspType<uint8_t, // readable
+              uint8_t, // lowerNCrit
+              uint8_t, // lowerCrit
+              uint8_t, // lowerNrecoverable
+              uint8_t, // upperNC
+              uint8_t, // upperCrit
+              uint8_t> // upperNRecoverable
+    ipmiSenGetSensorThresholds(uint8_t sensorNumber)
+{
+    std::string connection;
+    std::string path;
+
+    auto status = getSensorConnection(sensorNumber, connection, path);
+    if (status)
+    {
+        return ipmi::response(status);
+    }
+
+    SensorMap sensorMap;
+    if (!getSensorMap(connection, path, sensorMap))
+    {
+        return ipmi::responseResponseError();
+    }
+
+    IPMIThresholds thresholdData;
+    try
+    {
+        thresholdData = getIPMIThresholds(sensorMap);
+    }
+    catch (std::exception &)
+    {
+        return ipmi::responseResponseError();
+    }
+
+    uint8_t readable = 0;
+    uint8_t lowerNC = 0;
+    uint8_t lowerCritical = 0;
+    uint8_t lowerNonRecoverable = 0;
+    uint8_t upperNC = 0;
+    uint8_t upperCritical = 0;
+    uint8_t upperNonRecoverable = 0;
+
+    if (thresholdData.warningHigh)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::upperNonCritical);
+        upperNC = *thresholdData.warningHigh;
+    }
+    if (thresholdData.warningLow)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::lowerNonCritical);
+        lowerNC = *thresholdData.warningLow;
+    }
+
+    if (thresholdData.criticalHigh)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::upperCritical);
+        upperCritical = *thresholdData.criticalHigh;
+    }
+    if (thresholdData.criticalLow)
+    {
+        readable |=
+            1 << static_cast<uint8_t>(IPMIThresholdRespBits::lowerCritical);
+        lowerCritical = *thresholdData.criticalLow;
+    }
+
+    return ipmi::responseSuccess(readable, lowerNC, lowerCritical,
+                                 lowerNonRecoverable, upperNC, upperCritical,
+                                 upperNonRecoverable);
 }
 
 ipmi_ret_t ipmiSenGetSensorEventEnable(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
@@ -1313,10 +1341,10 @@
         ipmi::Privilege::User, ipmiSenGetSensorReading);
 
     // <Get Sensor Threshold>
-    ipmiPrintAndRegister(
-        NETFUN_SENSOR,
-        static_cast<ipmi_cmd_t>(IPMINetfnSensorCmds::ipmiCmdGetSensorThreshold),
-        nullptr, ipmiSenGetSensorThresholds, PRIVILEGE_USER);
+    ipmi::registerHandler(
+        ipmi::prioOemBase, NETFUN_SENSOR,
+        static_cast<ipmi::Cmd>(IPMINetfnSensorCmds::ipmiCmdGetSensorThreshold),
+        ipmi::Privilege::User, ipmiSenGetSensorThresholds);
 
     ipmiPrintAndRegister(
         NETFUN_SENSOR,