Populate the Type property in Item.Drive interface

By populating this property, bmcweb can populate the "MediaType"
property in the Drive schema.

Tested:
$ busctl get-property xyz.openbmc_project.eStoraged \
  /xyz/openbmc_project/inventory/storage/mmcblk0 \
  xyz.openbmc_project.Inventory.Item.Drive Type
s "xyz.openbmc_project.Inventory.Item.Drive.DriveType.SSD"

$ curl http://localhost:80/redfish/v1/Chassis/DCSCM/Drives/mmcblk0
{
...
  "MediaType": "SSD",
...
}

Signed-off-by: John Wedig <johnwedig@google.com>
Change-Id: I2cb6c7d3ec3b49e8d666da940d873f1117a0aa85
diff --git a/include/estoraged.hpp b/include/estoraged.hpp
index ec8f467..077b12e 100644
--- a/include/estoraged.hpp
+++ b/include/estoraged.hpp
@@ -46,6 +46,7 @@
      *  @param[in] locationCode - location code for the storage device
      *  @param[in] eraseMaxGeometry - max geometry to erase if it's specified
      *  @param[in] eraseMinGeometry - min geometry to erase if it's specified
+     *  @param[in] driveType - type of drive, e.g. HDD vs SSD
      *  @param[in] cryptInterface - (optional) pointer to CryptsetupInterface
      *    object
      *  @param[in] fsInterface - (optional) pointer to FilesystemInterface
@@ -56,7 +57,7 @@
               const std::string& luksName, uint64_t size, uint8_t lifeTime,
               const std::string& partNumber, const std::string& serialNumber,
               const std::string& locationCode, uint64_t eraseMaxGeometry,
-              uint64_t eraseMinGeometry,
+              uint64_t eraseMinGeometry, const std::string& driveType,
               std::unique_ptr<CryptsetupInterface> cryptInterface =
                   std::make_unique<Cryptsetup>(),
               std::unique_ptr<FilesystemInterface> fsInterface =
diff --git a/include/util.hpp b/include/util.hpp
index 8f5a0ff..7cc778a 100644
--- a/include/util.hpp
+++ b/include/util.hpp
@@ -18,14 +18,16 @@
     std::string locationCode;
     uint64_t eraseMaxGeometry;
     uint64_t eraseMinGeometry;
+    std::string driveType;
 
     DeviceInfo(std::filesystem::path& deviceFile,
                std::filesystem::path& sysfsDir, std::string& luksName,
                std::string& locationCode, uint64_t eraseMaxGeometry,
-               uint64_t eraseMinGeometry) :
+               uint64_t eraseMinGeometry, std::string& driveType) :
         deviceFile(deviceFile),
         sysfsDir(sysfsDir), luksName(luksName), locationCode(locationCode),
-        eraseMaxGeometry(eraseMaxGeometry), eraseMinGeometry(eraseMinGeometry)
+        eraseMaxGeometry(eraseMaxGeometry), eraseMinGeometry(eraseMinGeometry),
+        driveType(driveType)
     {}
 };
 
diff --git a/src/estoraged.cpp b/src/estoraged.cpp
index f9c69dc..d2ff1ef 100644
--- a/src/estoraged.cpp
+++ b/src/estoraged.cpp
@@ -38,7 +38,7 @@
                      uint8_t lifeTime, const std::string& partNumber,
                      const std::string& serialNumber,
                      const std::string& locationCode, uint64_t eraseMaxGeometry,
-                     uint64_t eraseMinGeometry,
+                     uint64_t eraseMinGeometry, const std::string& driveType,
                      std::unique_ptr<CryptsetupInterface> cryptInterface,
                      std::unique_ptr<FilesystemInterface> fsInterface) :
     devPath(devPath),
@@ -87,6 +87,9 @@
     driveInterface->register_property("Capacity", size);
     driveInterface->register_property("PredictedMediaLifeLeftPercent",
                                       lifeTime);
+    driveInterface->register_property(
+        "Type",
+        "xyz.openbmc_project.Inventory.Item.Drive.DriveType." + driveType);
     /* This registers the Locked property for the Drives interface.
      * Now it is the same as the volume Locked property */
     driveInterface->register_property_r(
diff --git a/src/main.cpp b/src/main.cpp
index 088d693..cb37791 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -99,11 +99,12 @@
             std::string partNumber = estoraged::util::getPartNumber(sysfsDir);
             std::string serialNumber =
                 estoraged::util::getSerialNumber(sysfsDir);
+            std::string driveType = deviceInfo->driveType;
             /* Create the storage object. */
             storageObjects[path] = std::make_unique<estoraged::EStoraged>(
                 objectServer, path, deviceFile, luksName, size, lifeleft,
                 partNumber, serialNumber, locationCode, eraseMaxGeometry,
-                eraseMinGeometry);
+                eraseMinGeometry, driveType);
             lg2::info("Created eStoraged object for path {PATH}", "PATH", path,
                       "REDFISH_MESSAGE_ID",
                       std::string("OpenBMC.0.1.CreateStorageObjects"));
diff --git a/src/test/estoraged_test.cpp b/src/test/estoraged_test.cpp
index 520c7ec..3d31112 100644
--- a/src/test/estoraged_test.cpp
+++ b/src/test/estoraged_test.cpp
@@ -46,6 +46,7 @@
     const std::string testPartNumber = "12345678";
     const std::string testSerialNumber = "ABCDEF1234";
     const std::string testLocationCode = "U102020";
+    const std::string testDriveType = "SSD";
     std::ofstream testFile;
     std::string passwordString;
     std::vector<uint8_t> password;
@@ -91,7 +92,7 @@
             *objectServer, testConfigPath, testFileName, testLuksDevName,
             testSize, testLifeTime, testPartNumber, testSerialNumber,
             testLocationCode, ERASE_MAX_GEOMETRY, ERASE_MIN_GEOMETRY,
-            std::move(cryptIface), std::move(fsIface));
+            testDriveType, std::move(cryptIface), std::move(fsIface));
     }
 
     void TearDown() override
diff --git a/src/test/util_test.cpp b/src/test/util_test.cpp
index 708454d..86e86e9 100644
--- a/src/test/util_test.cpp
+++ b/src/test/util_test.cpp
@@ -143,6 +143,7 @@
     EXPECT_EQ("U102020", result->locationCode);
     EXPECT_EQ(ERASE_MAX_GEOMETRY, result->eraseMaxGeometry);
     EXPECT_EQ(ERASE_MIN_GEOMETRY, result->eraseMinGeometry);
+    EXPECT_EQ("SSD", result->driveType);
 
     /* Delete the dummy files. */
     EXPECT_EQ(3U, std::filesystem::remove_all("mmcblk0"));
@@ -199,6 +200,7 @@
     EXPECT_EQ("U102020", result->locationCode);
     EXPECT_EQ(5566, result->eraseMaxGeometry);
     EXPECT_EQ(1234, result->eraseMinGeometry);
+    EXPECT_EQ("SSD", result->driveType);
 
     /* Delete the dummy files. */
     EXPECT_EQ(3U, std::filesystem::remove_all("mmcblk0"));
diff --git a/src/util.cpp b/src/util.cpp
index d32d59c..7bccdb1 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -203,13 +203,19 @@
     }
 
     /*
-     * Currently, we only support eMMC, so report an error for any other device
-     * types.
+     * Determine the drive type to report for this device. Note that we only
+     * support eMMC currently, so report an error for any other device types.
      */
-    std::string type = std::get<std::string>(typeVariant);
-    if (type.compare("EmmcDevice") != 0)
+    std::string deviceType = std::get<std::string>(typeVariant);
+    /* drive type to report in the Item.Drive dbus interface */
+    std::string driveType;
+    if (deviceType.compare("EmmcDevice") == 0)
     {
-        lg2::error("Unsupported device type {TYPE}", "TYPE", type,
+        driveType = "SSD";
+    }
+    else
+    {
+        lg2::error("Unsupported device type {TYPE}", "TYPE", deviceType,
                    "REDFISH_MESSAGE_ID",
                    std::string("OpenBMC.0.1.FindDeviceFail"));
         return std::nullopt;
@@ -247,9 +253,9 @@
                 deviceFile /= deviceName;
 
                 std::string luksName = "luks-" + deviceName.string();
-                return DeviceInfo{deviceFile,       sysfsDir,
-                                  luksName,         locationCode,
-                                  eraseMaxGeometry, eraseMinGeometry};
+                return DeviceInfo{
+                    deviceFile,       sysfsDir,         luksName, locationCode,
+                    eraseMaxGeometry, eraseMinGeometry, driveType};
             }
         }
         catch (...)