psu: Updates for power supply presence

Update the JSON file to indicate the minimum and maximum number of power
supplies this system can have.

Update the JSON file to have an array of power supply objects, each with
their various own properties. Each power supply will have:
1) An associated D-Bus path for the inventory. This will have the
   Present property.
2) An associated I2C bus number.
3) An associated I2C bus adddress.

Update PowerSupply class to have a present member variable, an
isPresent() accessor function, and two functions for updating the
presence. One function will be the call back function for either
inventory change events or interface added events, which will use
associated match member variables. The second function being one that
attempts to read the inventory Present property on startup. If reading
the Present property on startup fails, the property changed or interface
added events should work to get the value when that property is
available.

Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
Change-Id: Ib34510a6da66ba1b8f1e927093b3d10b09beb410
diff --git a/phosphor-power-supply/power_supply.hpp b/phosphor-power-supply/power_supply.hpp
index 3bfa77a..e5c1e76 100644
--- a/phosphor-power-supply/power_supply.hpp
+++ b/phosphor-power-supply/power_supply.hpp
@@ -1,5 +1,9 @@
 #pragma once
 
+#include "types.hpp"
+
+#include <sdbusplus/bus/match.hpp>
+
 namespace phosphor::power::psu
 {
 /**
@@ -9,7 +13,7 @@
 class PowerSupply
 {
   public:
-    PowerSupply();
+    PowerSupply() = delete;
     PowerSupply(const PowerSupply&) = delete;
     PowerSupply(PowerSupply&&) = delete;
     PowerSupply& operator=(const PowerSupply&) = delete;
@@ -17,6 +21,28 @@
     ~PowerSupply() = default;
 
     /**
+     * @param[in] invpath - string for inventory path to use
+     */
+    PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath) :
+        bus(bus), inventoryPath(invpath)
+    {
+        // Setup the functions to call when the D-Bus inventory path for the
+        // Present property changes.
+        presentMatch = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::propertiesChanged(inventoryPath,
+                                                            INVENTORY_IFACE),
+            [this](auto& msg) { this->inventoryChanged(msg); });
+        presentAddedMatch = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::interfacesAdded() +
+                sdbusplus::bus::match::rules::path_namespace(inventoryPath),
+            [this](auto& msg) { this->inventoryChanged(msg); });
+        // Get the current state of the Present property.
+        updatePresence();
+    }
+
+    /**
      * Power supply specific function to analyze for faults/errors.
      *
      * Various PMBus status bits will be checked for fault conditions.
@@ -58,9 +84,56 @@
     {
     }
 
+    /**
+     * @brief Accessor function to indicate present status
+     */
+    bool isPresent() const
+    {
+        return present;
+    }
+
   private:
+    /** @brief systemd bus member */
+    sdbusplus::bus::bus& bus;
+
     /** @brief True if a fault has already been found and not cleared */
     bool faultFound = false;
+
+    /**
+     * @brief D-Bus path to use for this power supply's inventory status.
+     **/
+    std::string inventoryPath;
+
+    /** @brief True if the power supply is present. */
+    bool present = false;
+
+    /** @brief D-Bus match variable used to subscribe to Present property
+     * changes.
+     **/
+    std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
+
+    /** @brief D-Bus match variable used to subscribe for Present property
+     * interface added.
+     */
+    std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
+
+    /**
+     *  @brief Updates the presence status by querying D-Bus
+     *
+     * The D-Bus inventory properties for this power supply will be read to
+     * determine if the power supply is present or not and update this
+     * object's present member variable to reflect current status.
+     **/
+    void updatePresence();
+
+    /**
+     * @brief Callback for inventory property changes
+     *
+     * Process change of Present property for power supply.
+     *
+     * @param[in]  msg - Data associated with Present change signal
+     **/
+    void inventoryChanged(sdbusplus::message::message& msg);
 };
 
 } // namespace phosphor::power::psu