rewrite Get Device ID using new provider API

Modify to use the new provider API. One by one, change calls to remove
any legacy API constructs.

Tested-by: ipmitool raw 6 1
           check for expected output

Change-Id: I59688627eb32670559c1defad0b7af8abeb84c75
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/apphandler.cpp b/apphandler.cpp
index 0d124fe..e5144ce 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -61,19 +61,6 @@
 namespace fs = std::filesystem;
 namespace variant_ns = sdbusplus::message::variant_ns;
 
-// Offset in get device id command.
-typedef struct
-{
-    uint8_t id;
-    uint8_t revision;
-    uint8_t fw[2];
-    uint8_t ipmi_ver;
-    uint8_t addn_dev_support;
-    uint8_t manuf_id[3];
-    uint8_t prod_id[2];
-    uint8_t aux[4];
-} __attribute__((packed)) ipmi_device_id_t;
-
 /**
  * @brief Returns the Version info from primary s/w object
  *
@@ -87,23 +74,30 @@
  */
 std::string getActiveSoftwareVersionInfo()
 {
-    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+    auto busp = getSdBus();
 
     std::string revision{};
-    auto objectTree =
-        ipmi::getAllDbusObjects(bus, softwareRoot, redundancyIntf, "");
-    if (objectTree.empty())
+    ipmi::ObjectTree objectTree;
+    try
     {
-        log<level::ERR>("No Obj has implemented the s/w redundancy interface",
-                        entry("INTERFACE=%s", redundancyIntf));
+        objectTree =
+            ipmi::getAllDbusObjects(*busp, softwareRoot, redundancyIntf);
+    }
+    catch (sdbusplus::exception::SdBusError& e)
+    {
+        log<level::ERR>("Failed to fetch redundancy object from dbus",
+                        entry("INTERFACE=%s", redundancyIntf),
+                        entry("ERRMSG=%s", e.what()));
         elog<InternalFailure>();
     }
 
     auto objectFound = false;
     for (auto& softObject : objectTree)
     {
-        auto service = ipmi::getService(bus, redundancyIntf, softObject.first);
-        auto objValueTree = ipmi::getManagedObjects(bus, service, softwareRoot);
+        auto service =
+            ipmi::getService(*busp, redundancyIntf, softObject.first);
+        auto objValueTree =
+            ipmi::getManagedObjects(*busp, service, softwareRoot);
 
         auto minPriority = 0xFF;
         for (const auto& objIter : objValueTree)
@@ -442,7 +436,7 @@
     char major;
     char minor;
     uint16_t d[2];
-} rev_t;
+} Revision;
 
 /* Currently supports the vx.x-x-[-x] and v1.x.x-x-[-x] format. It will     */
 /* return -1 if not in those formats, this routine knows how to parse       */
@@ -459,9 +453,8 @@
 /* Additional details : If the option group exists it will force Auxiliary  */
 /* Firmware Revision Information 4th byte to 1 indicating the build was     */
 /* derived with additional edits                                            */
-int convert_version(const char* p, rev_t* rev)
+int convertVersion(std::string s, Revision& rev)
 {
-    std::string s(p);
     std::string token;
     uint16_t commits;
 
@@ -476,7 +469,7 @@
         location = s.find_first_of(".");
         if (location != std::string::npos)
         {
-            rev->major =
+            rev.major =
                 static_cast<char>(std::stoi(s.substr(0, location), 0, 16));
             token = s.substr(location + 1);
         }
@@ -486,7 +479,7 @@
             location = token.find_first_of(".-");
             if (location != std::string::npos)
             {
-                rev->minor = static_cast<char>(
+                rev.minor = static_cast<char>(
                     std::stoi(token.substr(0, location), 0, 16));
                 token = token.substr(location + 1);
             }
@@ -498,7 +491,7 @@
         if (!token.empty())
         {
             commits = std::stoi(token.substr(0, location), 0, 16);
-            rev->d[0] = (commits >> 8) | (commits << 8);
+            rev.d[0] = (commits >> 8) | (commits << 8);
 
             // commit number we skip
             location = token.find_first_of(".-");
@@ -509,7 +502,7 @@
         }
         else
         {
-            rev->d[0] = 0;
+            rev.d[0] = 0;
         }
 
         if (location != std::string::npos)
@@ -527,36 +520,47 @@
 
         // We do this operation to get this displayed in least significant bytes
         // of ipmitool device id command.
-        rev->d[1] = (commits >> 8) | (commits << 8);
+        rev.d[1] = (commits >> 8) | (commits << 8);
     }
 
     return 0;
 }
 
-ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                                  ipmi_request_t request,
-                                  ipmi_response_t response,
-                                  ipmi_data_len_t data_len,
-                                  ipmi_context_t context)
+auto ipmiAppGetDeviceId() -> ipmi::RspType<uint8_t, // Device ID
+                                           uint8_t, // Device Revision
+                                           uint8_t, // Firmware Revision Major
+                                           uint8_t, // Firmware Revision minor
+                                           uint8_t, // IPMI version
+                                           uint8_t, // Additional device support
+                                           uint24_t, // MFG ID
+                                           uint16_t, // Product ID
+                                           uint32_t  // AUX info
+                                           >
 {
-    ipmi_ret_t rc = IPMI_CC_OK;
     int r = -1;
-    rev_t rev = {0};
-    static ipmi_device_id_t dev_id{};
+    Revision rev = {0};
+    static struct
+    {
+        uint8_t id;
+        uint8_t revision;
+        uint8_t fw[2];
+        uint8_t ipmiVer;
+        uint8_t addnDevSupport;
+        uint24_t manufId;
+        uint16_t prodId;
+        uint32_t aux;
+    } devId;
     static bool dev_id_initialized = false;
     const char* filename = "/usr/share/ipmi-providers/dev_id.json";
     constexpr auto ipmiDevIdStateShift = 7;
     constexpr auto ipmiDevIdFw1Mask = ~(1 << ipmiDevIdStateShift);
 
-    // Data length
-    *data_len = sizeof(dev_id);
-
     if (!dev_id_initialized)
     {
         try
         {
             auto version = getActiveSoftwareVersionInfo();
-            r = convert_version(version.c_str(), &rev);
+            r = convertVersion(version, rev);
         }
         catch (const std::exception& e)
         {
@@ -571,34 +575,28 @@
             // or self-initialization in progress.
             // The availability may change in run time, so mask here
             // and initialize later.
-            dev_id.fw[0] = rev.major & ipmiDevIdFw1Mask;
+            devId.fw[0] = rev.major & ipmiDevIdFw1Mask;
 
             rev.minor = (rev.minor > 99 ? 99 : rev.minor);
-            dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
-            std::memcpy(&dev_id.aux, rev.d, 4);
+            devId.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
+            std::memcpy(&devId.aux, rev.d, 4);
         }
 
         // IPMI Spec version 2.0
-        dev_id.ipmi_ver = 2;
+        devId.ipmiVer = 2;
 
-        std::ifstream dev_id_file(filename);
-        if (dev_id_file.is_open())
+        std::ifstream devIdFile(filename);
+        if (devIdFile.is_open())
         {
-            auto data = nlohmann::json::parse(dev_id_file, nullptr, false);
+            auto data = nlohmann::json::parse(devIdFile, nullptr, false);
             if (!data.is_discarded())
             {
-                dev_id.id = data.value("id", 0);
-                dev_id.revision = data.value("revision", 0);
-                dev_id.addn_dev_support = data.value("addn_dev_support", 0);
-                dev_id.manuf_id[2] = data.value("manuf_id", 0) >> 16;
-                dev_id.manuf_id[1] = data.value("manuf_id", 0) >> 8;
-                dev_id.manuf_id[0] = data.value("manuf_id", 0);
-                dev_id.prod_id[1] = data.value("prod_id", 0) >> 8;
-                dev_id.prod_id[0] = data.value("prod_id", 0);
-                dev_id.aux[3] = data.value("aux", 0);
-                dev_id.aux[2] = data.value("aux", 0) >> 8;
-                dev_id.aux[1] = data.value("aux", 0) >> 16;
-                dev_id.aux[0] = data.value("aux", 0) >> 24;
+                devId.id = data.value("id", 0);
+                devId.revision = data.value("revision", 0);
+                devId.addnDevSupport = data.value("addn_dev_support", 0);
+                devId.manufId = data.value("manuf_id", 0);
+                devId.prodId = data.value("prod_id", 0);
+                devId.aux = data.value("aux", 0);
 
                 // Don't read the file every time if successful
                 dev_id_initialized = true;
@@ -606,27 +604,26 @@
             else
             {
                 log<level::ERR>("Device ID JSON parser failure");
-                rc = IPMI_CC_UNSPECIFIED_ERROR;
+                return ipmi::response(ipmi::ccUnspecifiedError);
             }
         }
         else
         {
             log<level::ERR>("Device ID file not found");
-            rc = IPMI_CC_UNSPECIFIED_ERROR;
+            return ipmi::response(ipmi::ccUnspecifiedError);
         }
     }
 
     // Set availability to the actual current BMC state
-    dev_id.fw[0] &= ipmiDevIdFw1Mask;
+    devId.fw[0] &= ipmiDevIdFw1Mask;
     if (!getCurrentBmcState())
     {
-        dev_id.fw[0] |= (1 << ipmiDevIdStateShift);
+        devId.fw[0] |= (1 << ipmiDevIdStateShift);
     }
 
-    // Pack the actual response
-    std::memcpy(response, &dev_id, *data_len);
-
-    return rc;
+    return ipmi::responseSuccess(
+        devId.id, devId.revision, devId.fw[0], devId.fw[1], devId.ipmiVer,
+        devId.addnDevSupport, devId.manufId, devId.prodId, devId.aux);
 }
 
 ipmi_ret_t ipmi_app_get_self_test_results(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
@@ -1069,6 +1066,11 @@
 
 void register_netfn_app_functions()
 {
+    // <Get Device ID>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetDeviceId, ipmi::Privilege::User,
+                          ipmiAppGetDeviceId);
+
     // <Get BT Interface Capabilities>
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL,
                            ipmi_app_get_bt_capabilities, PRIVILEGE_USER);
@@ -1089,10 +1091,6 @@
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_WD, NULL,
                            ipmi_app_watchdog_get, PRIVILEGE_OPERATOR);
 
-    // <Get Device ID>
-    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_ID, NULL,
-                           ipmi_app_get_device_id, PRIVILEGE_USER);
-
     // <Get Self Test Results>
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SELF_TEST_RESULTS, NULL,
                            ipmi_app_get_self_test_results, PRIVILEGE_USER);