Redfish: Implement ResetBios action

This action resets the BIOS attributes to default.

Tested:
GET test:
1. $ curl -k -H "X-Auth-Token: $token" https://${bmc}/redfish/v1/Systems/system
{
  ...
  "Bios": {
    "@odata.id": "/redfish/v1/Systems/system/Bios"
  },
  ...
}
2. $ curl -k -H "X-Auth-Token: $token" https://${bmc}/redfish/v1/Systems/system/Bios
{
  "@odata.id": "/redfish/v1/Systems/system/Bios",
  "@odata.type": "#Bios.v1_1_0.Bios",
  "Actions": {
    "#Bios.ResetBios": {
      "target": "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios"
    }
  },
  "Description": "BIOS Configuration Service",
  "Id": "BIOS",
  "Name": "BIOS Configuration"
}

POST test:
1. Change gard list:
 # ./gard list
 No GARD entries to display
 # ./gard create /Sys0/Node0/Proc1/EQ1/EX1/Core0
 # ./gard list
  ID       | Error    | Type       | Path
 -----------------------------------------------------------------------
  00000001 | 00000000 | Manual     | /Sys0/Node0/Proc1/EQ1/EX1/Core0
 =======================================================================
2. Reset bios:
 # curl -k -H "X-Auth-Token: $token" -X POST https://${bmc}/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios
3. Check gard list again:
 # ./gard list
 No GARD entries to display

Validator tool test:
 Counter({'pass': 3001, 'skipOptional': 2475, 'metadataNamespaces': 1605,
 'passGet': 191, 'serviceNamespaces': 72, 'invalidPropertyValue': 10,
 'passAction': 7, 'optionalAction': 6, 'warningPresent': 6, 'warnDeprecated':
 2, 'unverifiedComplexAdditional': 1})
 Validation has succeeded.

Signed-off-by: Carol Wang <wangkair@cn.ibm.com>
Change-Id: I0cba966bfde04566001b6df07ad15217f627c327
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index d0e0531..715b4a4 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -16,6 +16,7 @@
 #pragma once
 
 #include "../lib/account_service.hpp"
+#include "../lib/bios.hpp"
 #include "../lib/certificate_service.hpp"
 #include "../lib/chassis.hpp"
 #include "../lib/cpudimm.hpp"
@@ -121,6 +122,8 @@
         nodes.emplace_back(std::make_unique<SystemsCollection>(app));
         nodes.emplace_back(std::make_unique<Systems>(app));
         nodes.emplace_back(std::make_unique<SystemActionsReset>(app));
+        nodes.emplace_back(std::make_unique<BiosService>(app));
+        nodes.emplace_back(std::make_unique<BiosReset>(app));
 #ifdef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES
         nodes.emplace_back(std::make_unique<DBusLogServiceActionsClear>(app));
         nodes.emplace_back(std::make_unique<DBusEventLogEntryCollection>(app));
diff --git a/redfish-core/lib/bios.hpp b/redfish-core/lib/bios.hpp
new file mode 100644
index 0000000..94f1cb9
--- /dev/null
+++ b/redfish-core/lib/bios.hpp
@@ -0,0 +1,73 @@
+#pragma once
+
+#include "node.hpp"
+
+namespace redfish
+{
+/**
+ * BiosService class supports handle get method for bios.
+ */
+class BiosService : public Node
+{
+  public:
+    BiosService(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/Bios/")
+    {
+        entityPrivileges = {{boost::beast::http::verb::get, {{"Login"}}}};
+    }
+
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        auto asyncResp = std::make_shared<AsyncResp>(res);
+
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/Systems/system/Bios";
+        asyncResp->res.jsonValue["@odata.type"] = "#Bios.v1_1_0.Bios";
+        asyncResp->res.jsonValue["Name"] = "BIOS Configuration";
+        asyncResp->res.jsonValue["Description"] = "BIOS Configuration Service";
+        asyncResp->res.jsonValue["Id"] = "BIOS";
+        asyncResp->res.jsonValue["Actions"]["#Bios.ResetBios"] = {
+            {"target",
+             "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios"}};
+    }
+};
+/**
+ * BiosReset class supports handle POST method for Reset bios.
+ * The class retrieves and sends data directly to D-Bus.
+ */
+class BiosReset : public Node
+{
+  public:
+    BiosReset(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios/")
+    {
+        entityPrivileges = {
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
+
+  private:
+    /**
+     * Function handles POST method request.
+     * Analyzes POST body message before sends Reset request data to D-Bus.
+     */
+    void doPost(crow::Response &res, const crow::Request &req,
+                const std::vector<std::string> &params) override
+    {
+        auto asyncResp = std::make_shared<AsyncResp>(res);
+
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](const boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Failed to reset bios: " << ec;
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+            },
+            "org.open_power.Software.Host.Updater",
+            "/xyz/openbmc_project/software",
+            "xyz.openbmc_project.Common.FactoryReset", "Reset");
+    }
+};
+} // namespace redfish
\ No newline at end of file
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index ce12ed7..93eb403 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -1710,6 +1710,9 @@
         res.jsonValue["LogServices"] = {
             {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
 
+        res.jsonValue["Bios"] = {
+            {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
+
         res.jsonValue["Links"]["ManagedBy"] = {
             {{"@odata.id", "/redfish/v1/Managers/bmc"}}};