Add beep support for PSU

Spec requires that system will beep with pattern 1-5-1-4
if there is any PSU failure or config error.

Tested:
With two PSUs, disconnect one AC cable, or unplug one PSU,
to trigger the psu failure/config error, there is a beep.

Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Change-Id: I8664400164298fa4a35f82b79e4bf417481aabb0
diff --git a/src/PSUEvent.cpp b/src/PSUEvent.cpp
index 0849500..1e228fe 100644
--- a/src/PSUEvent.cpp
+++ b/src/PSUEvent.cpp
@@ -30,8 +30,9 @@
 #include <vector>
 
 PSUCombineEvent::PSUCombineEvent(
-    sdbusplus::asio::object_server& objectServer, boost::asio::io_service& io,
-    const std::string& psuName,
+    sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::io_service& io, const std::string& psuName,
     boost::container::flat_map<std::string, std::vector<std::string>>&
         eventPathList,
     boost::container::flat_map<
@@ -65,7 +66,7 @@
         for (const auto& path : pathList.second)
         {
             events[eventPSUName].emplace_back(std::make_unique<PSUSubEvent>(
-                eventInterface, path, io, eventName, eventName, assert,
+                eventInterface, path, conn, io, eventName, eventName, assert,
                 combineEvent, state, psuName));
             asserts.emplace_back(assert);
             states.emplace_back(state);
@@ -85,7 +86,7 @@
             for (const auto& path : pathList.second)
             {
                 events[eventPSUName].emplace_back(std::make_unique<PSUSubEvent>(
-                    eventInterface, path, io, groupEventName,
+                    eventInterface, path, conn, io, groupEventName,
                     groupPathList.first, assert, combineEvent, state, psuName));
                 asserts.emplace_back(assert);
                 states.emplace_back(state);
@@ -128,15 +129,16 @@
 
 PSUSubEvent::PSUSubEvent(
     std::shared_ptr<sdbusplus::asio::dbus_interface> eventInterface,
-    const std::string& path, boost::asio::io_service& io,
-    const std::string& groupEventName, const std::string& eventName,
+    const std::string& path, std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::io_service& io, const std::string& groupEventName,
+    const std::string& eventName,
     std::shared_ptr<std::set<std::string>> asserts,
     std::shared_ptr<std::set<std::string>> combineEvent,
     std::shared_ptr<bool> state, const std::string& psuName) :
     eventInterface(eventInterface),
     asserts(asserts), combineEvent(combineEvent), assertState(state),
     errCount(0), path(path), eventName(eventName), waitTimer(io), inputDev(io),
-    psuName(psuName), groupEventName(groupEventName)
+    psuName(psuName), groupEventName(groupEventName), systemBus(conn)
 {
     fd = open(path.c_str(), O_RDONLY);
     if (fd < 0)
@@ -303,6 +305,15 @@
             *assertState = true;
             if (!assertMessage.empty())
             {
+                // For failure and configure error, spec requires a beep
+                if ((assertMessage == "OpenBMC.0.1.PowerSupplyFailed") ||
+                    (assertMessage ==
+                     "OpenBMC.0.1.PowerSupplyConfigurationError"))
+                {
+                    std::cout << " beep for " << assertMessage << "\n";
+                    beep(beepPSUFailure);
+                }
+
                 // Fan Failed has two args
                 std::string sendMessage = eventName + " assert";
                 if (assertMessage == "OpenBMC.0.1.PowerSupplyFanFailed")
@@ -332,3 +343,17 @@
     }
     value = newValue;
 }
+
+void PSUSubEvent::beep(const uint8_t& beepPriority)
+{
+    systemBus->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "beep error (ec = " << ec << ")\n";
+                return;
+            }
+        },
+        "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode",
+        "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority));
+}