Sync w/ updated power control interfaces

setPowerState/getPowerState methods are removed.
all properties are removed except PGood and State.
return value of forcePowerOff is changed to bool from int32

TestBy:
    Ipmi command and click buttons
Change-Id: I0b5e51cea959594acf04257c566893da6ffe7d26
Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
diff --git a/power-control/inc/power_control.hpp b/power-control/inc/power_control.hpp
index f68b71d..ae98a8d 100644
--- a/power-control/inc/power_control.hpp
+++ b/power-control/inc/power_control.hpp
@@ -25,12 +25,29 @@
 #include <xyz/openbmc_project/Chassis/Control/Power/server.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 
-// static constexpr size_t POLLING_INTERVAL_MS = 500;
-
+static constexpr size_t POLLING_INTERVAL_MS = 500;
 const static constexpr char* PGOOD_PIN = "PGOOD";
 const static constexpr char* POWER_UP_PIN = "POWER_UP_PIN";
 
-const static constexpr size_t POWER_UP_PIN_PULSE_TIME_MS = 200;
+const static constexpr size_t POWER_PULSE_TIME_MS = 200;
+const static constexpr size_t RESET_PULSE_TIME_MS = 500;
+const static constexpr char* PowerControlPath =
+    "/xyz/openbmc_project/Chassis/Control/Power0";
+const static constexpr char* PowerControlIntf =
+    "xyz.openbmc_project.Chassis.Control.Power";
+const static constexpr char* PowerButtonPath =
+    "/xyz/openbmc_project/Chassis/Buttons/Power0";
+const static constexpr char* PowerButtonIntf =
+    "xyz.openbmc_project.Chassis.Buttons.Power";
+const static constexpr char* ResetButtonPath =
+    "/xyz/openbmc_project/Chassis/Buttons/Reset0";
+const static constexpr char* ResetButtonIntf =
+    "xyz.openbmc_project.Chassis.Buttons.Reset";
+
+const static constexpr int32_t powerStateOff = 0;
+const static constexpr int32_t powerStateOn = 1;
+const static constexpr int32_t powerStateReset = 2;
+const static constexpr int32_t powerStateMax = 3;
 
 struct EventDeleter
 {
@@ -51,7 +68,69 @@
                  // phosphor::watchdog::EventPtr event,
                  sd_event_io_handler_t handler = PowerControl::EventHandler) :
         sdbusplus::server::object_t<pwr_control>(bus, path),
-        bus(bus), callbackHandler(handler)
+        bus(bus), callbackHandler(handler),
+        powerButtonPressedSignal(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::member("Pressed") +
+                sdbusplus::bus::match::rules::path(PowerButtonPath) +
+                sdbusplus::bus::match::rules::interface(PowerButtonIntf),
+            [this](sdbusplus::message::message& msg) {
+                phosphor::logging::log<phosphor::logging::level::INFO>(
+                    "powerButtonPressed callback function is called...");
+                if (powerStateOn == this->state())
+                {
+                    this->state(powerStateOff);
+                }
+                else if (powerStateOff == this->state())
+                {
+                    this->state(powerStateOn);
+                }
+                else
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "UNKNOWN power state");
+                }
+                return;
+            }),
+        resetButtonPressedSignal(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::member("Pressed") +
+                sdbusplus::bus::match::rules::path(ResetButtonPath) +
+                sdbusplus::bus::match::rules::interface(ResetButtonIntf),
+            [this](sdbusplus::message::message& msg) {
+                phosphor::logging::log<phosphor::logging::level::INFO>(
+                    "resetButtonPressed callback function is called...");
+                this->state(powerStateReset);
+                return;
+            }),
+        propertiesChangedSignal(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::member("PropertiesChanged") +
+                sdbusplus::bus::match::rules::path(PowerControlPath) +
+                sdbusplus::bus::match::rules::interface(PowerControlIntf),
+            [this](sdbusplus::message::message& msg) {
+                phosphor::logging::log<phosphor::logging::level::INFO>(
+                    "PowerControl propertiesChangedSignal callback function is "
+                    "called...");
+                std::string objectName;
+                std::map<std::string,
+                         sdbusplus::message::variant<int, bool, std::string>>
+                    msgData;
+                msg.read(objectName, msgData);
+                // Check if it was the Value property that changed.
+                auto valPropMap = msgData.find("State");
+                {
+                    if (valPropMap != msgData.end())
+                    {
+                        this->setPowerState(
+                            sdbusplus::message::variant_ns::get<int>(
+                                valPropMap->second));
+                    }
+                }
+            })
     {
         int ret = -1;
         char buf = '0';
@@ -166,13 +245,16 @@
     }
 
     bool forcePowerOff() override;
-    // todo: when dbus interfaces is fixed, these should be override
-    int32_t setPowerState(int32_t newState); // override;
-    int32_t getPowerState();                 // override;
 
   private:
+    int reset_out_fd;
     int power_up_fd;
     int pgood_fd;
     sdbusplus::bus::bus& bus;
     sd_event_io_handler_t callbackHandler;
+    int32_t setPowerState(int newState);
+    int32_t triggerReset();
+    sdbusplus::bus::match_t propertiesChangedSignal;
+    sdbusplus::bus::match_t powerButtonPressedSignal;
+    sdbusplus::bus::match_t resetButtonPressedSignal;
 };
diff --git a/power-control/service-files/intel-power-start@.service b/power-control/service-files/intel-power-start@.service
index 763c115..2bb601c 100644
--- a/power-control/service-files/intel-power-start@.service
+++ b/power-control/service-files/intel-power-start@.service
@@ -7,8 +7,8 @@
 
 [Service]
 Type=oneshot
-ExecStart=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
-          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power setPowerState i 1"
+ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
+          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power State i 1"
 SyslogIdentifier=intel-power-start
 StartLimitInterval=0
 
diff --git a/power-control/service-files/intel-power-stop@.service b/power-control/service-files/intel-power-stop@.service
index 5d0e46f..aac1946 100644
--- a/power-control/service-files/intel-power-stop@.service
+++ b/power-control/service-files/intel-power-stop@.service
@@ -7,8 +7,8 @@
 
 [Service]
 Type=oneshot
-ExecStart=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
-          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power setPowerState i 0"
+ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
+          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power State i 0"
 SyslogIdentifier=intel-power-stop
 StartLimitInterval=0
 
diff --git a/power-control/service-files/intel-power-warm-reset@.service b/power-control/service-files/intel-power-warm-reset@.service
index c8bd4fc..ede20ac 100644
--- a/power-control/service-files/intel-power-warm-reset@.service
+++ b/power-control/service-files/intel-power-warm-reset@.service
@@ -7,8 +7,8 @@
 
 [Service]
 Type=oneshot
-ExecStart=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
-          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power setPowerState i 2"
+ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
+          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power State i 2"
 SyslogIdentifier=intel-power-warm-reset
 
 [Install]
diff --git a/power-control/service-files/obmc-chassis-hard-poweroff@.target b/power-control/service-files/obmc-chassis-hard-poweroff@.target
index 5f53251..9b66218 100644
--- a/power-control/service-files/obmc-chassis-hard-poweroff@.target
+++ b/power-control/service-files/obmc-chassis-hard-poweroff@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Chassis%i (Hard Power Off)
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-chassis-poweron@%i.target
diff --git a/power-control/service-files/obmc-chassis-poweroff@.target b/power-control/service-files/obmc-chassis-poweroff@.target
index aa026cf..1bc0691 100644
--- a/power-control/service-files/obmc-chassis-poweroff@.target
+++ b/power-control/service-files/obmc-chassis-poweroff@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Chassis%i (Power Off)
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-chassis-poweron@%i.target
diff --git a/power-control/service-files/obmc-chassis-poweron@.target b/power-control/service-files/obmc-chassis-poweron@.target
index 572dfa0..4b77af6 100644
--- a/power-control/service-files/obmc-chassis-poweron@.target
+++ b/power-control/service-files/obmc-chassis-poweron@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Chassis%i (Power On)
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-chassis-poweroff@%i.target
diff --git a/power-control/service-files/obmc-chassis-powerreset@.target b/power-control/service-files/obmc-chassis-powerreset@.target
index 8d7c47e..6f93925 100644
--- a/power-control/service-files/obmc-chassis-powerreset@.target
+++ b/power-control/service-files/obmc-chassis-powerreset@.target
@@ -4,4 +4,4 @@
 RefuseManualStop=yes
 
 [Install]
-WantedBy={SYSTEMD_DEFAULT_TARGET}
+WantedBy=obmc-standby.target
\ No newline at end of file
diff --git a/power-control/service-files/obmc-host-reboot@.target b/power-control/service-files/obmc-host-reboot@.target
index 2522012..e779ab2 100644
--- a/power-control/service-files/obmc-host-reboot@.target
+++ b/power-control/service-files/obmc-host-reboot@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Reboot Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-host-startmin@%i.target
diff --git a/power-control/service-files/obmc-host-soft-reboot@.target b/power-control/service-files/obmc-host-soft-reboot@.target
index ae620c4..0bb2938 100644
--- a/power-control/service-files/obmc-host-soft-reboot@.target
+++ b/power-control/service-files/obmc-host-soft-reboot@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Soft Reboot Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-host-startmin@%i.target
diff --git a/power-control/service-files/obmc-host-start@.target b/power-control/service-files/obmc-host-start@.target
index 96e6ea1..38f76c6 100644
--- a/power-control/service-files/obmc-host-start@.target
+++ b/power-control/service-files/obmc-host-start@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Start Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-host-stop@%i.target
diff --git a/power-control/service-files/obmc-host-startmin@.target b/power-control/service-files/obmc-host-startmin@.target
index bb79370..98f044f 100644
--- a/power-control/service-files/obmc-host-startmin@.target
+++ b/power-control/service-files/obmc-host-startmin@.target
@@ -1,6 +1,6 @@
 [Unit]
 Description=Start Host%i Minimum
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
diff --git a/power-control/service-files/obmc-host-stop@.target b/power-control/service-files/obmc-host-stop@.target
index df371b9..5178e83 100644
--- a/power-control/service-files/obmc-host-stop@.target
+++ b/power-control/service-files/obmc-host-stop@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Stop Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-host-startmin@%i.target
diff --git a/power-control/service-files/obmc-host-warm-reset@.target b/power-control/service-files/obmc-host-warm-reset@.target
index 6d4cbcf..8c6fa5a 100644
--- a/power-control/service-files/obmc-host-warm-reset@.target
+++ b/power-control/service-files/obmc-host-warm-reset@.target
@@ -1,7 +1,7 @@
 [Unit]
 Description=Warm reset Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.target
 Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
 Conflicts=obmc-host-stop@%i.target
diff --git a/power-control/service-files/op-reset-chassis-running@.service b/power-control/service-files/op-reset-chassis-running@.service
index 3280d0a..2d6d32c 100644
--- a/power-control/service-files/op-reset-chassis-running@.service
+++ b/power-control/service-files/op-reset-chassis-running@.service
@@ -9,7 +9,7 @@
 [Service]
 RemainAfterExit=no
 Type=oneshot
-ExecStart=/bin/sh -c "if [ $(busctl get-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power pgood | sed 's/i\s*[1]/on/' | grep on | wc -l) != 0 ]; then mkdir -p /run/openbmc/ && touch /run/openbmc/chassis@%i-on; fi"
+ExecStart=/bin/sh -c "if [ $(busctl get-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power PGood | sed 's/i\s*[1]/on/' | grep on | wc -l) != 0 ]; then mkdir -p /run/openbmc/ && touch /run/openbmc/chassis@%i-on; fi"
 
 [Install]
 WantedBy=obmc-chassis-powerreset@%i.target
diff --git a/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service b/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
index fe69931..3bbfb17 100644
--- a/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
+++ b/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
@@ -10,8 +10,8 @@
 ExecStart=/usr/bin/env power-control
 SyslogIdentifier=power-control
 Type=dbus
-BusName={BUSNAME}
+BusName=xyz.openbmc_project.Chassis.Control.Power
 
 [Install]
-WantedBy={SYSTEMD_DEFAULT_TARGET}
+WantedBy=obmc-standby.target
 
diff --git a/power-control/src/power_control.cpp b/power-control/src/power_control.cpp
index 3014370..4a3ca4b 100644
--- a/power-control/src/power_control.cpp
+++ b/power-control/src/power_control.cpp
@@ -20,15 +20,69 @@
     return true;
 }
 
-int32_t PowerControl::setPowerState(int32_t newState)
+int32_t PowerControl::triggerReset()
 {
     int ret = 0;
     int count = 0;
     char buf = '0';
 
+    phosphor::logging::log<phosphor::logging::level::DEBUG>("triggerReset");
+
+    ret = ::lseek(reset_out_fd, 0, SEEK_SET);
+    if (ret < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>("lseek error!");
+        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+            IOError();
+    }
+
+    buf = '0';
+
+    ret = ::write(reset_out_fd, &buf, sizeof(buf));
+    if (ret < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
+        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+            IOError();
+    }
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(RESET_PULSE_TIME_MS));
+
+    buf = '1';
+    ret = ::write(reset_out_fd, &buf, sizeof(buf));
+    if (ret < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
+        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+            IOError();
+    }
+    return 0;
+}
+
+int32_t PowerControl::setPowerState(int newState)
+{
+    int ret = 0;
+    int count = 0;
+    char buf = '0';
+
+    if (newState < 0 || newState >= powerStateMax)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "error! invalid parameter!");
+        return -1;
+    }
+
     phosphor::logging::log<phosphor::logging::level::DEBUG>(
         "setPowerState", phosphor::logging::entry("NEWSTATE=%d", newState));
 
+    if (powerStateReset == newState)
+    {
+        phosphor::logging::log<phosphor::logging::level::DEBUG>(
+            "setPowerState system reset");
+        triggerReset();
+        return 0;
+    }
+
     if (state() == newState)
     {
         phosphor::logging::log<phosphor::logging::level::WARNING>(
@@ -37,6 +91,8 @@
         return 0;
     }
 
+    state(newState);
+
     ret = ::lseek(power_up_fd, 0, SEEK_SET);
     if (ret < 0)
     {
@@ -45,42 +101,57 @@
             IOError();
     }
 
-    /*
-    This power control just handle out pin "POWER_UP_PIN", change it
-    to low "0" form high "1" and set it back to high after over 200ms,
-    which will notify host (PCH) to switch power. Host to determine it
-    is power on or power off operation based on current power status.
-    For BMC (power control), just need to notify host (PCH) to switch
-    power, don't need to judge it should power on or off.
-    */
     buf = '0';
+
     ret = ::write(power_up_fd, &buf, sizeof(buf));
     if (ret < 0)
     {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "write error for setting 0 !");
+        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
         throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
             IOError();
     }
 
-    std::this_thread::sleep_for(
-        std::chrono::milliseconds(POWER_UP_PIN_PULSE_TIME_MS));
+    phosphor::logging::log<phosphor::logging::level::DEBUG>(
+        "setPowerState power on");
+    std::this_thread::sleep_for(std::chrono::milliseconds(POWER_PULSE_TIME_MS));
 
     buf = '1';
     ret = ::write(power_up_fd, &buf, sizeof(buf));
     if (ret < 0)
     {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "write error for setting 1 !");
+        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
         throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
             IOError();
     }
 
-    state(newState);
+    if (0 == newState)
+    {
+        /*
+         * For power off, currently there is a known issue, the "long-press"
+         * power button cannot power off the host, a workaround is perform force
+         * power off after waitting for a while
+         */
+        std::this_thread::sleep_for(
+            std::chrono::milliseconds(POWER_PULSE_TIME_MS));
+        if (1 == pGood())
+        { // still on, force off!
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "Perform force power off");
+            count = 0;
+            do
+            {
+                if (count++ > 5)
+                {
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "forcePowerOff error!");
+                    throw sdbusplus::xyz::openbmc_project::Chassis::Common::
+                        Error::IOError();
+                }
+                ret = forcePowerOff();
+                std::this_thread::sleep_for(
+                    std::chrono::milliseconds(POLLING_INTERVAL_MS));
+            } while (ret != 0);
+        }
+    }
     return 0;
 }
-
-int32_t PowerControl::getPowerState()
-{
-    return state();
-}