Add flags for bmc  modes transitions

1. When /run/bm-drive-cleaning-done.flag is present, it means cleaning
   is done and we are in BM_MODE. Also, it is acked by renaming flag to
   bm-drive-cleaning-done-ack.flag
2. if not case 1, when /run/bm-drive-cleaning-done-ack.flag is present,
   it means the cleaing is done and acked
3. if not case 2, when bm-ready.flag is present, it means we are in
   BM_CLEANING_MODE. /run/bm-drive-cleaning.flag is created if needed
4. otherwise, we are in NON_BM_MODE

Tested:
bm-ready.flag is not present. Respond Non-BM mode:

ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x10
 79 2b 00 10 00

bm-ready.flah is present. For next call, respond Cleaning Mode and
bm-drive-cleaning.flag is created:

ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x10
 79 2b 00 10 02

keep responding Cleaning Mode until bm-drive-cleaning-done.flag is
created. So cleaning is done and for next call, respond BM mode and
rename bm-drive-cleaning-done.flag to bm-drive-cleaning-done-ack.flag:

ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x10
 79 2b 00 10 01

Change-Id: Id8a6049550631c30c68a536313b81a8d800fede0
Signed-off-by: Hao Zhou <haoooamazing@google.com>
diff --git a/handler.cpp b/handler.cpp
index 9bbd082..4046871 100644
--- a/handler.cpp
+++ b/handler.cpp
@@ -68,21 +68,58 @@
 using InternalFailure =
     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
 
+static constexpr auto bmDriveCleaningFlagPath = "/run/bm-drive-cleaning.flag";
+static constexpr auto bmDriveCleaningDoneFlagPath =
+    "/run/bm-drive-cleaning-done.flag";
+static constexpr auto bmDriveCleaningDoneAckFlagPath =
+    "/run/bm-drive-cleaning-done-ack.flag";
+
 uint8_t isBmcInBareMetalMode()
 {
 #if BARE_METAL
     return static_cast<uint8_t>(BmcMode::BM_MODE);
 #else
     std::error_code ec;
-    if (fs::exists(BM_SIGNAL_PATH, ec))
+
+    if (fs::exists(bmDriveCleaningDoneAckFlagPath, ec))
     {
-        std::fprintf(stderr, "%s exists so we must be in BM mode\n",
-                     BM_SIGNAL_PATH);
+        std::fprintf(
+            stderr,
+            "%s exists so we acked cleaning done and must be in BM mode\n",
+            bmDriveCleaningDoneAckFlagPath);
         return static_cast<uint8_t>(BmcMode::BM_MODE);
     }
 
-    std::fprintf(stderr, "Unable to find %s so we must not be in BM mode\n",
-                 BM_SIGNAL_PATH);
+    if (fs::exists(bmDriveCleaningDoneFlagPath, ec))
+    {
+        fs::rename(bmDriveCleaningDoneFlagPath, bmDriveCleaningDoneAckFlagPath,
+                   ec);
+        std::fprintf(
+            stderr,
+            "%s exists so we just finished cleaning and must be in BM mode\n",
+            bmDriveCleaningDoneFlagPath);
+        return static_cast<uint8_t>(BmcMode::BM_MODE);
+    }
+
+    if (fs::exists(BM_SIGNAL_PATH, ec))
+    {
+        if (!fs::exists(bmDriveCleaningFlagPath, ec))
+        {
+            std::ofstream ofs;
+            ofs.open(bmDriveCleaningFlagPath, std::ofstream::out);
+            ofs.close();
+        }
+
+        std::fprintf(
+            stderr,
+            "%s exists and no done/ack flag, we must be in BM cleaning mode\n",
+            BM_SIGNAL_PATH);
+        return static_cast<uint8_t>(BmcMode::BM_CLEANING_MODE);
+    }
+
+    std::fprintf(
+        stderr,
+        "Unable to find any BM state files so we must not be in BM mode\n");
     return static_cast<uint8_t>(BmcMode::NON_BM_MODE);
 #endif
 }