bmcweb: Add Warthog OEM Support

Expose all Warthog GPIO values as Warthog OEM for easiler acces ad part
of the work to deprecate old method of log entries.

Tested:
```
{
 "@odata.id": "/redfish/v1/Systems/system/Storage/warthog_storage_1#/StorageControllers/1",
 "@odata.type": "#Storage.v1_9_1.StorageController",
 "Links": {
   "Google": {
     "Warthog": {
       "@odata.type": "#GoogleWarthog.v1_0_0.GoogleWarthog",
       "BootFailureCount": 0,
       "DebugMode": false,
       "DisableWatchdog": false,
       "FruEepromWriteProtect": true,
       "ManufacturingMode": false,
       "MorristownOtpWriteEnable": false,
       "MorristownOtpWriteProtect": false,
       "Name": "Warthog GPIO Action Info",
       "PwrseqPgood": true,
       "PwrseqState": "PgoodPlpOk",
       "SpiImgSelect": 0,
       "TriggerPowerCycle": false,
       "WatchdogTriggered": false
     }
   }
 },
 ...
}
```

Google-Bug-Id: 270449147
Google-Bug-Id: 245814416
Google-Bug-Id: 239578152
Change-Id: I2724e86bc3178f7d81980a8cfb2b8e9e41516242
diff --git a/recipes-phosphor/interfaces/bmcweb/DOWNSTREAM_0001-Support-Google-OEM-Warthog.patch b/recipes-phosphor/interfaces/bmcweb/DOWNSTREAM_0001-Support-Google-OEM-Warthog.patch
new file mode 100644
index 0000000..108a6ac
--- /dev/null
+++ b/recipes-phosphor/interfaces/bmcweb/DOWNSTREAM_0001-Support-Google-OEM-Warthog.patch
@@ -0,0 +1,188 @@
+From e7aec2513bcddc1149ec69e2ed2b842c753ae7a9 Mon Sep 17 00:00:00 2001
+From: Willy Tu <wltu@google.com>
+Date: Wed, 15 Feb 2023 09:26:03 -0800
+Subject: [PATCH] Support Google OEM Warthog
+
+Expose all Warthog GPIO values as Warthog OEM for easiler acces ad part
+of the work to deprecate old method of log entries.
+
+Tested:
+```
+    {
+      "@odata.id": "/redfish/v1/Systems/system/Storage/warthog_storage_1#/StorageControllers/1",
+      "@odata.type": "#Storage.v1_9_1.StorageController",
+      "Links": {
+        "Google": {
+          "Warthog": {
+            "@odata.type": "#GoogleWarthog.v1_0_0.GoogleWarthog",
+            "BootFailureCount": 0,
+            "DebugMode": false,
+            "DisableWatchdog": false,
+            "FruEepromWriteProtect": true,
+            "ManufacturingMode": false,
+            "MorristownOtpWriteEnable": false,
+            "MorristownOtpWriteProtect": false,
+            "Name": "Warthog GPIO Action Info",
+            "PwrseqPgood": true,
+            "PwrseqState": "PgoodPlpOk",
+            "SpiImgSelect": 0,
+            "TriggerPowerCycle": false,
+	    "TriggerReset": false,
+            "WatchdogTriggered": false
+          }
+        }
+      },
+      }
+```
+
+Patch Tracking Bug: b/270449147
+Upstream info / review: N/A
+Upstream-Status: Inappropriate [Internal only]
+Justification:
+Warthog OEM is internal only change to support legacy usage to support Warthog.
+We don't plan to use it to support future storage devices
+
+Google-Bug-Id: 239578152
+Google-Bug-Id: 245814416
+Change-Id: If4465e5c3d9515cf260f750948ac72302274716f
+Signed-off-by: Willy Tu <wltu@google.com>
+---
+ redfish-core/lib/storage.hpp | 115 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 115 insertions(+)
+
+diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
+index c40ea9b2..90640496 100644
+--- a/redfish-core/lib/storage.hpp
++++ b/redfish-core/lib/storage.hpp
+@@ -216,6 +216,120 @@ inline void getStorageControllerLocation(
+     }
+ }
+
++inline void
++    populateWarthogInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
++                        const std::string& connection, const std::string& path,
++                        size_t index)
++{
++    // Warthog GPIO
++    sdbusplus::asio::getAllProperties(
++        *crow::connections::systemBus, connection, path,
++        "com.google.gbmc.ssd.warthog",
++        [asyncResp, index](
++            const boost::system::error_code ec2,
++            const std::vector<std::pair<
++                std::string, dbus::utility::DbusVariantType>>& propertiesList) {
++        if (ec2)
++        {
++            // this interface isn't necessary
++            return;
++        }
++
++        const bool* manufacturingMode = nullptr;
++        const bool* pwrseqPgood = nullptr;
++        const bool* watchdogTriggered = nullptr;
++        const bool* fruEepromWriteProtect = nullptr;
++        const bool* morristownOtpWriteProtect = nullptr;
++        const bool* triggerPowerCycle = nullptr;
++        const bool* triggerReset = nullptr;
++        const bool* disableWatchdog = nullptr;
++        const bool* debugMode = nullptr;
++        const bool* morristownOtpWriteEnable = nullptr;
++        const uint64_t* spiImgSelect = nullptr;
++        const uint64_t* bootFailureCount = nullptr;
++        const std::string* pwrseqState = nullptr;
++
++        const bool success = sdbusplus::unpackPropertiesNoThrow(
++            dbus_utils::UnpackErrorPrinter(), propertiesList,
++            "ManufacturingMode", manufacturingMode, "WatchdogTriggered",
++            watchdogTriggered, "PwrseqPgood", pwrseqPgood,
++            "FruEepromWriteProtect", fruEepromWriteProtect,
++            "MorristownOtpWriteProtect", morristownOtpWriteProtect,
++            "TriggerPowerCycle", triggerPowerCycle, "TriggerReset",
++            triggerReset, "DisableWatchdog", disableWatchdog, "DebugMode",
++            debugMode, "MorristownOtpWriteEnable", morristownOtpWriteEnable,
++            "SpiImgSelect", spiImgSelect, "BootFailureCount", bootFailureCount,
++            "PwrseqState", pwrseqState);
++
++        if (!success)
++        {
++            BMCWEB_LOG_CRITICAL << "Failed to parse Warthog Arguments";
++            messages::internalError(asyncResp->res);
++            return;
++        }
++
++        nlohmann::json& controller =
++            asyncResp->res.jsonValue["StorageControllers"][index];
++        nlohmann::json::object_t warthog;
++        warthog["@odata.type"] = "#GoogleWarthog.v1_0_0.GoogleWarthog";
++        if (manufacturingMode != nullptr)
++        {
++            warthog["ManufacturingMode"] = *manufacturingMode;
++        }
++        if (pwrseqPgood != nullptr)
++        {
++            warthog["PwrseqPgood"] = *pwrseqPgood;
++        }
++        if (watchdogTriggered != nullptr)
++        {
++            warthog["WatchdogTriggered"] = *watchdogTriggered;
++        }
++        if (fruEepromWriteProtect != nullptr)
++        {
++            warthog["FruEepromWriteProtect"] = *fruEepromWriteProtect;
++        }
++        if (morristownOtpWriteProtect != nullptr)
++        {
++            warthog["MorristownOtpWriteProtect"] = *morristownOtpWriteProtect;
++        }
++        if (triggerPowerCycle != nullptr)
++        {
++            warthog["TriggerPowerCycle"] = *triggerPowerCycle;
++        }
++        if (triggerReset != nullptr)
++        {
++            warthog["TriggerReset"] = *triggerReset;
++        }
++        if (disableWatchdog != nullptr)
++        {
++            warthog["DisableWatchdog"] = *disableWatchdog;
++        }
++        if (debugMode != nullptr)
++        {
++            warthog["DebugMode"] = *debugMode;
++        }
++        if (morristownOtpWriteEnable != nullptr)
++        {
++            warthog["MorristownOtpWriteEnable"] = *morristownOtpWriteEnable;
++        }
++        if (spiImgSelect != nullptr)
++        {
++            warthog["SpiImgSelect"] = *spiImgSelect;
++        }
++        if (bootFailureCount != nullptr)
++        {
++            warthog["BootFailureCount"] = *bootFailureCount;
++        }
++        if (pwrseqState != nullptr)
++        {
++            warthog["PwrseqState"] = *pwrseqState;
++        }
++
++        warthog["Name"] = "Warthog GPIO Action Info";
++        controller["Links"]["Google"]["Warthog"] = std::move(warthog);
++        });
++}
++
+ inline void populateStorageControllers(
+     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+     const std::string& connectionName, const std::string& path,
+@@ -239,6 +353,7 @@ inline void populateStorageControllers(
+     storageController["Status"]["State"] = "Enabled";
+     getStorageControllerLocation(asyncResp, connectionName, path, interfaces,
+                                  index);
++    populateWarthogInfo(asyncResp, connectionName, path, index);
+
+     sdbusplus::asio::getProperty<bool>(
+         *crow::connections::systemBus, connectionName, path,
+--
+2.39.2.722.g9855ee24e9-goog
+
diff --git a/recipes-phosphor/interfaces/bmcweb_%.bbappend b/recipes-phosphor/interfaces/bmcweb_%.bbappend
index 099c7a1..b62e518 100644
--- a/recipes-phosphor/interfaces/bmcweb_%.bbappend
+++ b/recipes-phosphor/interfaces/bmcweb_%.bbappend
@@ -36,6 +36,7 @@
   file://0010-LogEntry-Link-device-log-to-Drive-and-Processor.patch \
   file://0011-log_services-Add-OriginOfCondition-to-DeviceLog.patch \
   file://0012-chassis-Set-Chassis.Reset-to-support-only-RackMount-.patch \
+  file://DOWNSTREAM_0001-Support-Google-OEM-Warthog.patch \
 "
 
 # TTF build specific patches migrated to non-TTF