chassis-state-manager: Add multi-chassis support

Add multi-chassis management support, each chassis bus separates by
giving a unique chassis id.

Current code only support single chassis, and alway assume bus name is
"xyz.openbmc_project.State.Chassis".

This patch allow user to launch chassis-state-manager with a chassis id,
and chassis id is added into service bus name for identification.

Because there are many places hardcode with bus name
"xyz.openbmc_project.State.Chassis", if chassis id is 0,
chassis-state-manager will request both
"xyz.openbmc_project.State.Chassis" and
"xyz.openbmc_project.State.Chassis0" bus name to meet backwards
compatibility.

Tested on Bletchley:
root@bletchley:~# busctl tree xyz.openbmc_project.State.Chassis
`-/xyz
  `-/xyz/openbmc_project
    `-/xyz/openbmc_project/state
      `-/xyz/openbmc_project/state/chassis0
root@bletchley:~# busctl tree xyz.openbmc_project.State.Chassis0
`-/xyz
  `-/xyz/openbmc_project
    `-/xyz/openbmc_project/state
      `-/xyz/openbmc_project/state/chassis0
root@bletchley:~# busctl tree xyz.openbmc_project.State.Chassis1
`-/xyz
  `-/xyz/openbmc_project
    `-/xyz/openbmc_project/state
      `-/xyz/openbmc_project/state/chassis1
......

patch dependencies:
https://gerrit.openbmc-project.xyz/c/openbmc/phosphor-state-manager/+/51465

Signed-off-by: Potin Lai <potin.lai@quantatw.com>
Change-Id: I2ce3e9ab2c95a2688143f4e3775da164a5c33c19
diff --git a/chassis_state_manager.cpp b/chassis_state_manager.cpp
index 60be584..7acbef5 100644
--- a/chassis_state_manager.cpp
+++ b/chassis_state_manager.cpp
@@ -6,6 +6,8 @@
 #include "xyz/openbmc_project/Common/error.hpp"
 #include "xyz/openbmc_project/State/Shutdown/Power/error.hpp"
 
+#include <fmt/format.h>
+
 #include <cereal/archives/json.hpp>
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/lg2.hpp>
@@ -33,13 +35,13 @@
 using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
 using sdbusplus::xyz::openbmc_project::State::Shutdown::Power::Error::Blackout;
 using sdbusplus::xyz::openbmc_project::State::Shutdown::Power::Error::Regulator;
-constexpr auto CHASSIS_STATE_POWEROFF_TGT = "obmc-chassis-poweroff@0.target";
-constexpr auto CHASSIS_STATE_HARD_POWEROFF_TGT =
-    "obmc-chassis-hard-poweroff@0.target";
-constexpr auto CHASSIS_STATE_POWERON_TGT = "obmc-chassis-poweron@0.target";
-constexpr auto RESET_HOST_SENSORS_SVC =
-    "phosphor-reset-sensor-states@0.service";
-
+constexpr auto CHASSIS_STATE_POWEROFF_TGT_FMT =
+    "obmc-chassis-poweroff@{}.target";
+constexpr auto CHASSIS_STATE_HARD_POWEROFF_TGT_FMT =
+    "obmc-chassis-hard-poweroff@{}.target";
+constexpr auto CHASSIS_STATE_POWERON_TGT_FMT = "obmc-chassis-poweron@{}.target";
+constexpr auto RESET_HOST_SENSORS_SVC_FMT =
+    "phosphor-reset-sensor-states@{}.service";
 constexpr auto ACTIVE_STATE = "active";
 constexpr auto ACTIVATING_STATE = "activating";
 
@@ -48,13 +50,6 @@
 constexpr uint STATE_FULLY_CHARGED = 4;
 constexpr uint BATTERY_LVL_FULL = 8;
 
-/* Map a transition to it's systemd target */
-const std::map<server::Chassis::Transition, std::string> SYSTEMD_TARGET_TABLE =
-    {
-        // Use the hard off target to ensure we shutdown immediately
-        {server::Chassis::Transition::Off, CHASSIS_STATE_HARD_POWEROFF_TGT},
-        {server::Chassis::Transition::On, CHASSIS_STATE_POWERON_TGT}};
-
 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
 constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
@@ -85,6 +80,14 @@
     return;
 }
 
+void Chassis::createSystemdTargetTable()
+{
+    systemdTargetTable = {
+        // Use the hard off target to ensure we shutdown immediately
+        {Transition::Off, fmt::format(CHASSIS_STATE_HARD_POWEROFF_TGT_FMT, id)},
+        {Transition::On, fmt::format(CHASSIS_STATE_POWERON_TGT_FMT, id)}};
+}
+
 // TODO - Will be rewritten once sdbusplus client bindings are in place
 //        and persistent storage design is in place and sdbusplus
 //        has read property function
@@ -136,7 +139,7 @@
                         "Chassis power was on before the BMC reboot and it is off now");
 
                     // Reset host sensors since system is off now
-                    startUnit(RESET_HOST_SENSORS_SVC);
+                    startUnit(fmt::format(RESET_HOST_SENSORS_SVC_FMT, id));
 
                     setStateChangeTime();
 
@@ -410,16 +413,17 @@
         return 0;
     }
 
-    if ((newStateUnit == CHASSIS_STATE_POWEROFF_TGT) &&
-        (newStateResult == "done") && (!stateActive(CHASSIS_STATE_POWERON_TGT)))
+    if ((newStateUnit == systemdTargetTable[Transition::Off]) &&
+        (newStateResult == "done") &&
+        (!stateActive(systemdTargetTable[Transition::On])))
     {
         info("Received signal that power OFF is complete");
         this->currentPowerState(server::Chassis::PowerState::Off);
         this->setStateChangeTime();
     }
-    else if ((newStateUnit == CHASSIS_STATE_POWERON_TGT) &&
+    else if ((newStateUnit == systemdTargetTable[Transition::On]) &&
              (newStateResult == "done") &&
-             (stateActive(CHASSIS_STATE_POWERON_TGT)))
+             (stateActive(systemdTargetTable[Transition::On])))
     {
         info("Received signal that power ON is complete");
         this->currentPowerState(server::Chassis::PowerState::On);
@@ -448,7 +452,7 @@
 
     info("Change to Chassis Requested Power State: {REQ_POWER_TRAN}",
          "REQ_POWER_TRAN", value);
-    startUnit(SYSTEMD_TARGET_TABLE.find(value)->second);
+    startUnit(systemdTargetTable.find(value)->second);
     return server::Chassis::requestedPowerTransition(value);
 }