dbus_handler: Add DBus interfaces to export boot info

Adding DBus interfaces for adding/getting checkpoint and duration from
DBus.

Tested:
```
\# DBus interfaces are added
bmc:~# busctl introspect \
com.google.gbmc.boot_time_monitor \
/xyz/openbmc_project/time/boot/host0
NAME                                     TYPE      SIGNATURE  RESULT/VALUE  FLAGS
......
xyz.openbmc_project.Time.Boot.Checkpoint interface -          -             -
.GetCheckpointList                       method    -          a(sxx)        -
.RebootComplete                          method    -          -             -
.SetCheckpoint                           method    sxx        -             -
xyz.openbmc_project.Time.Boot.Duration   interface -          -             -
.GetAdditionalDurations                  method    -          a(sx)         -
.SetDuration                             method    sx         -             -
xyz.openbmc_project.Time.Boot.Statistic  interface -          -             -
.IsRebooting                             property  b          true          emits-change

\# Try to call `SetCheckpoint`
bmc:~# busctl call \
com.google.gbmc.boot_time_monitor \
/xyz/openbmc_project/time/boot/host0 \
xyz.openbmc_project.Time.Boot.Checkpoint \
SetCheckpoint sxx "checkpoint1" 0 0

\# Check if it set correctly
bmc:~# busctl --verbose call \
com.google.gbmc.boot_time_monitor \
/xyz/openbmc_project/time/boot/host0 \
xyz.openbmc_project.Time.Boot.Checkpoint \
GetCheckpointList
MESSAGE "a(sxx)" {
        ARRAY "(sxx)" {
                STRUCT "sxx" {
                        STRING "ShutDownEnd";
                        INT64 1693915751696;
                        INT64 39660;
                };
                STRUCT "sxx" {
                        STRING "PowerOffEnd";
                        INT64 1693915885932;
                        INT64 173900;
                };
                STRUCT "sxx" {
                        STRING "checkpoint1";
                        INT64 1693919548471;
                        INT64 3740020;
                };
        };
};
```

Google-Bug-Id: 296530445
Change-Id: Iee6fd10190d275195959cace296e9b2795beb2d0
Signed-off-by: Michael Shen <gpgpgp@google.com>
diff --git a/include/dbus_handler.hpp b/include/dbus_handler.hpp
new file mode 100644
index 0000000..847125e
--- /dev/null
+++ b/include/dbus_handler.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "boot_manager.hpp"
+#include "utils.hpp"
+
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <xyz/openbmc_project/Time/Boot/Checkpoint/server.hpp>
+#include <xyz/openbmc_project/Time/Boot/Duration/server.hpp>
+#include <xyz/openbmc_project/Time/Boot/Statistic/server.hpp>
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+namespace boot_time_monitor
+{
+
+class DbusHandler :
+    sdbusplus::server::object::object<
+        sdbusplus::xyz::openbmc_project::Time::Boot::server::Duration>,
+    sdbusplus::server::object::object<
+        sdbusplus::xyz::openbmc_project::Time::Boot::server::Checkpoint>,
+    sdbusplus::server::object::object<
+        sdbusplus::xyz::openbmc_project::Time::Boot::server::Statistic>
+{
+  public:
+    DbusHandler(sdbusplus::bus::bus& dbus, const std::string& objPath,
+                std::shared_ptr<BootManagerIface> bm,
+                std::shared_ptr<UtilIface> util);
+
+    void setCheckpoint(std::string checkpointName, int64_t wallTime,
+                       int64_t selfMeasuredDuration) override;
+    std::vector<std::tuple<std::string, int64_t, int64_t>>
+        getCheckpointList() override;
+    void rebootComplete() override;
+    void setDuration(std::string durationName, int64_t duration) override;
+    std::vector<std::tuple<std::string, int64_t>>
+        getAdditionalDurations() override;
+    bool isRebooting() const override;
+
+  private:
+    std::shared_ptr<BootManagerIface> bm;
+    std::shared_ptr<UtilIface> util;
+};
+
+} // namespace boot_time_monitor
diff --git a/include/host_monitor_app.hpp b/include/host_monitor_app.hpp
index adf9c2c..7cd678c 100644
--- a/include/host_monitor_app.hpp
+++ b/include/host_monitor_app.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "boot_manager.hpp"
+#include "dbus_handler.hpp"
 #include "utils.hpp"
 
 #include <sdbusplus/bus.hpp>
@@ -28,6 +29,7 @@
     std::shared_ptr<FileUtil> cpCSV;
     std::shared_ptr<FileUtil> durCSV;
     std::shared_ptr<BootManager> bm;
+    std::shared_ptr<DbusHandler> dh;
 };
 
 } // namespace boot_time_monitor
diff --git a/src/dbus_handler.cpp b/src/dbus_handler.cpp
new file mode 100644
index 0000000..8dcf281
--- /dev/null
+++ b/src/dbus_handler.cpp
@@ -0,0 +1,91 @@
+#include "dbus_handler.hpp"
+
+#include "boot_manager.hpp"
+
+#include <fmt/printf.h>
+
+#include <boost/container/flat_map.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
+#include <xyz/openbmc_project/Time/Boot/Checkpoint/server.hpp>
+#include <xyz/openbmc_project/Time/Boot/Duration/server.hpp>
+#include <xyz/openbmc_project/Time/Boot/Statistic/server.hpp>
+
+#include <tuple>
+
+namespace boot_time_monitor
+{
+
+DbusHandler::DbusHandler(sdbusplus::bus::bus& dbus, const std::string& objPath,
+                         std::shared_ptr<BootManagerIface> bm,
+                         std::shared_ptr<UtilIface> util) :
+    sdbusplus::server::object::object<Duration>(dbus, objPath.c_str()),
+    sdbusplus::server::object::object<Checkpoint>(dbus, objPath.c_str()),
+    sdbusplus::server::object::object<Statistic>(dbus, objPath.c_str()), bm(bm),
+    util(util)
+{}
+
+void DbusHandler::setCheckpoint(std::string checkpointName, int64_t wallTime,
+                                int64_t selfMeasuredDuration)
+{
+    if (!util->isValidName(checkpointName))
+    {
+        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
+    }
+
+    bm->setCheckpoint(checkpointName, wallTime, selfMeasuredDuration);
+}
+
+std::vector<std::tuple<std::string, int64_t, int64_t>>
+    DbusHandler::getCheckpointList()
+{
+    std::vector<std::tuple<std::string, int64_t, int64_t>> result;
+    for (const auto& cp : bm->getCheckpoints())
+    {
+        result.emplace_back(std::make_tuple(cp.name, cp.wallTime, cp.monoTime));
+    }
+    return result;
+}
+
+void DbusHandler::rebootComplete()
+{
+    if (!isRebooting())
+    {
+        fmt::print(stderr,
+                   "[{}]: Not rebooting. Skip this `rebootComplete` command\n",
+                   __FUNCTION__);
+        return;
+    }
+
+    bm->notifyComplete();
+}
+
+void DbusHandler::setDuration(std::string durationName, int64_t duration)
+{
+    if (!util->isValidName(durationName))
+    {
+        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
+    }
+
+    bm->setDuration(durationName, duration);
+}
+
+std::vector<std::tuple<std::string, int64_t>>
+    DbusHandler::getAdditionalDurations()
+{
+    std::vector<std::tuple<std::string, int64_t>> result;
+    for (const auto& dur : bm->getDurations())
+    {
+        result.emplace_back(std::make_tuple(dur.name, dur.duration));
+    }
+    return result;
+}
+
+bool DbusHandler::isRebooting() const
+{
+    return bm->isRebooting();
+}
+
+} // namespace boot_time_monitor
diff --git a/src/host_monitor_app.cpp b/src/host_monitor_app.cpp
index a434a1f..8918f89 100644
--- a/src/host_monitor_app.cpp
+++ b/src/host_monitor_app.cpp
@@ -1,6 +1,7 @@
 #include "host_monitor_app.hpp"
 
 #include "boot_manager.hpp"
+#include "dbus_handler.hpp"
 #include "utils.hpp"
 
 #include <fmt/printf.h>
@@ -36,6 +37,7 @@
     cpCSV = std::make_shared<FileUtil>(util->getCPPath(kNodeName, false));
     durCSV = std::make_shared<FileUtil>(util->getDurPath(kNodeName, false));
     bm = std::make_shared<BootManager>(util, cpCSV, durCSV);
+    dh = std::make_shared<DbusHandler>(bus, kObjPath.data(), bm, util);
 
     powerMatcher = std::make_unique<sdbusplus::bus::match::match>(
         bus,
diff --git a/src/meson.build b/src/meson.build
index 9ee614d..d9983ae 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -26,6 +26,7 @@
   'host_monitor_app.cpp',
   'utils.cpp',
   'boot_manager.cpp',
+  'dbus_handler.cpp',
   generated_sources,
   include_directories: boot_time_monitor_incs,
   implicit_include_directories: false,