redfish: Add EncryptionStatus to Drive

This change takes the locked, and EncryptionStatus properties from
Drives interfaces, and creates the redfish property EncryptionStatus.

Tested:
$ wget -qO- \
http://localhost:80/redfish/v1/Chassis/AgoraV2/Drives/mmcblk0
{
  "@odata.context": "/redfish/v1/$metadata#Drive.Drive",
  "@odata.id": "/redfish/v1/Chassis/Drives/mmcblk0",
  "@odata.type": "#Drive.v1_7_0.Drive",
  "CapacityBytes": 15634268160,
  "EncryptionStatus": "Unencrypted",
  "Id": "mmcblk0",
  "Links": {
    "Chassis": "Enabled"
  },
  "Name": "mmcblk0",
  "Status": {
    "State": "Enabled"
  }
}

Running the redfish Validator did not show any errors from this change.

Change-Id: Ic7b58614466535b3fd6b8c097050d3e9c8de8203
Signed-off-by: John Edward Broadbent <jebr@google.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
diff --git a/Redfish.md b/Redfish.md
index 1cdce98..aa5ab89 100644
--- a/Redfish.md
+++ b/Redfish.md
@@ -904,6 +904,7 @@
 #### Storage
 
 - CapacityBytes
+- EncryptionStatus
 - Links
 - Status
 
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index fe4842c..3bc8419 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -17,6 +17,7 @@
 
 #include "app.hpp"
 #include "dbus_utility.hpp"
+#include "generated/enums/drive.hpp"
 #include "health.hpp"
 #include "human_sort.hpp"
 #include "openbmc_dbus_rest.hpp"
@@ -440,6 +441,8 @@
             // this interface isn't required
             return;
         }
+        const std::string* encryptionStatus = nullptr;
+        const bool* isLocked = nullptr;
         for (const std::pair<std::string, dbus::utility::DbusVariantType>&
                  property : propertiesList)
         {
@@ -524,7 +527,55 @@
                         *lifeLeft;
                 }
             }
+            else if (propertyName == "EncryptionStatus")
+            {
+                encryptionStatus = std::get_if<std::string>(&property.second);
+                if (encryptionStatus == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "Illegal property: EncryptionStatus";
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+            }
+            else if (propertyName == "Locked")
+            {
+                isLocked = std::get_if<bool>(&property.second);
+                if (isLocked == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "Illegal property: Locked";
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+            }
         }
+
+        if (encryptionStatus == nullptr || isLocked == nullptr ||
+            *encryptionStatus ==
+                "xyz.openbmc_project.Drive.DriveEncryptionState.Unknown")
+        {
+            return;
+        }
+        if (*encryptionStatus !=
+            "xyz.openbmc_project.Drive.DriveEncryptionState.Encrypted")
+        {
+            //"The drive is not currently encrypted."
+            asyncResp->res.jsonValue["EncryptionStatus"] =
+                drive::EncryptionStatus::Unencrypted;
+            return;
+        }
+        if (*isLocked)
+        {
+            //"The drive is currently encrypted and the data is not
+            // accessible to the user."
+            asyncResp->res.jsonValue["EncryptionStatus"] =
+                drive::EncryptionStatus::Locked;
+            return;
+        }
+        // if not locked
+        // "The drive is currently encrypted but the data is accessible
+        // to the user in unencrypted form."
+        asyncResp->res.jsonValue["EncryptionStatus"] =
+            drive::EncryptionStatus::Unlocked;
         });
 }