BMCDump: dump subtype input parameter support

The BMC dump is not accepting any parameters to specify the type of
dump or level of data to be collected. It was always creating a default
user-requested dump.

This commit allows for the specification of the dump type during the
dump creation process. A new table has been added in a new header file
which stores the valid dump types. When a new dump is requested, the
specified dump type is verified against this table. If no dump type is
mentioned, a user-requested BMC dump is created for backward
compatibility. If an invalid dump type is mentioned, an Invalid
Argument exception is thrown.

Tested:
- Create BMC dump with no arguments
- Create BMC dump with type as user
- Create a error log dump and make sure other types of dumps
  which is using internal interface is not impacted.

Change-Id: I79f68be6ac6892ac7754b7221db64c22330b1822
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
diff --git a/dump_manager_bmc.cpp b/dump_manager_bmc.cpp
index 8161f41..6c99099 100644
--- a/dump_manager_bmc.cpp
+++ b/dump_manager_bmc.cpp
@@ -4,6 +4,7 @@
 
 #include "bmc_dump_entry.hpp"
 #include "dump_internal.hpp"
+#include "dump_types.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 #include "xyz/openbmc_project/Dump/Create/error.hpp"
 
@@ -31,6 +32,7 @@
 using namespace phosphor::logging;
 
 bool Manager::fUserDumpInProgress = false;
+constexpr auto BMC_DUMP = "BMC_DUMP";
 
 namespace internal
 {
@@ -50,11 +52,6 @@
         lg2::warning("BMC dump accepts not more than 2 additional parameters");
     }
 
-    if (Manager::fUserDumpInProgress == true)
-    {
-        elog<sdbusplus::xyz::openbmc_project::Common::Error::Unavailable>();
-    }
-
     // Get the originator id and type from params
     std::string originatorId;
     originatorTypes originatorType;
@@ -62,8 +59,29 @@
     phosphor::dump::extractOriginatorProperties(params, originatorId,
                                                 originatorType);
 
-    std::vector<std::string> paths;
-    auto id = captureDump(Type::UserRequested, paths);
+    using CreateParameters =
+        sdbusplus::common::xyz::openbmc_project::dump::Create::CreateParameters;
+
+    DumpTypes dumpType = DumpTypes::USER;
+    std::string type = extractParameter<std::string>(
+        convertCreateParametersToString(CreateParameters::DumpType), params);
+    if (!type.empty())
+    {
+        dumpType = validateDumpType(type, BMC_DUMP);
+    }
+    std::string path = extractParameter<std::string>(
+        convertCreateParametersToString(CreateParameters::FilePath), params);
+
+    if ((Manager::fUserDumpInProgress == true) && (dumpType == DumpTypes::USER))
+    {
+        lg2::info("Another user initiated dump in progress");
+        elog<sdbusplus::xyz::openbmc_project::Common::Error::Unavailable>();
+    }
+
+    lg2::info("Initiating new BMC dump with type: {TYPE} path: {PATH}", "TYPE",
+              dumpTypeToString(dumpType).value(), "PATH", path);
+
+    auto id = captureDump(dumpType, path);
 
     // Entry Object path.
     auto objPath = std::filesystem::path(baseEntryPath) / std::to_string(id);
@@ -89,13 +107,23 @@
         elog<InternalFailure>();
     }
 
-    Manager::fUserDumpInProgress = true;
+    if (dumpType == DumpTypes::USER)
+    {
+        Manager::fUserDumpInProgress = true;
+    }
     return objPath.string();
 }
 
 uint32_t Manager::captureDump(Type type,
                               const std::vector<std::string>& fullPaths)
 {
+    // get dreport type map entry
+    auto tempType = TypeMap.find(type);
+    return captureDump(stringToDumpType(tempType->second).value(),
+                       fullPaths.front());
+}
+uint32_t Manager::captureDump(DumpTypes type, const std::string& path)
+{
     // Get Dump size.
     auto size = getAllowedSize();
 
@@ -107,12 +135,10 @@
         auto id = std::to_string(lastEntryId + 1);
         dumpPath /= id;
 
-        // get dreport type map entry
-        auto tempType = TypeMap.find(type);
+        auto strType = dumpTypeToString(type).value();
         execl("/usr/bin/dreport", "dreport", "-d", dumpPath.c_str(), "-i",
               id.c_str(), "-s", std::to_string(size).c_str(), "-q", "-v", "-p",
-              fullPaths.empty() ? "" : fullPaths.front().c_str(), "-t",
-              tempType->second.c_str(), nullptr);
+              path.empty() ? "" : path.c_str(), "-t", strType.c_str(), nullptr);
 
         // dreport script execution is failed.
         auto error = errno;
@@ -124,7 +150,7 @@
     else if (pid > 0)
     {
         Child::Callback callback = [this, type, pid](Child&, const siginfo_t*) {
-            if (type == Type::UserRequested)
+            if (type == DumpTypes::USER)
             {
                 lg2::info("User initiated dump completed, resetting flag");
                 Manager::fUserDumpInProgress = false;