xref: /openbmc/phosphor-power/phosphor-power-supply/util.hpp (revision 5d4a9c78acf0d019b8dd083ac2aad4e0af241481)
1 #pragma once
2 #include "util_base.hpp"
3 #include "utility.hpp"
4 #include "xyz/openbmc_project/Common/error.hpp"
5 
6 #include <fmt/format.h>
7 
8 #include <gpiod.hpp>
9 #include <phosphor-logging/elog-errors.hpp>
10 #include <phosphor-logging/elog.hpp>
11 #include <phosphor-logging/log.hpp>
12 
13 namespace phosphor::power::psu
14 {
15 
16 class Util : public UtilBase
17 {
18   public:
19     bool getPresence(sdbusplus::bus::bus& bus,
20                      const std::string& invpath) const override
21     {
22         bool present = false;
23 
24         // Use getProperty utility function to get presence status.
25         util::getProperty(INVENTORY_IFACE, PRESENT_PROP, invpath,
26                           INVENTORY_MGR_IFACE, bus, present);
27 
28         return present;
29     }
30 
31     void setPresence(sdbusplus::bus::bus& bus, const std::string& invpath,
32                      bool present, const std::string& name) const override
33     {
34         using InternalFailure =
35             sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
36         using Property = std::string;
37         using Value = std::variant<bool, std::string>;
38         // Association between property and its value
39         using PropertyMap = std::map<Property, Value>;
40         PropertyMap invProp;
41 
42         invProp.emplace("Present", present);
43         invProp.emplace("PrettyName", name);
44 
45         using Interface = std::string;
46         // Association between interface and the D-Bus property map
47         using InterfaceMap = std::map<Interface, PropertyMap>;
48         InterfaceMap invIntf;
49         invIntf.emplace("xyz.openbmc_project.Inventory.Item",
50                         std::move(invProp));
51 
52         Interface extraIface = "xyz.openbmc_project.Inventory.Item.PowerSupply";
53 
54         invIntf.emplace(extraIface, PropertyMap());
55 
56         using Object = sdbusplus::message::object_path;
57         // Association between object and the interface map
58         using ObjectMap = std::map<Object, InterfaceMap>;
59         ObjectMap invObj;
60         invObj.emplace(std::move(invpath), std::move(invIntf));
61 
62         using namespace phosphor::logging;
63         log<level::INFO>(fmt::format("Updating inventory present property. "
64                                      "present:{} invpath:{} name:{}",
65                                      present, invpath, name)
66                              .c_str());
67 
68         try
69         {
70             auto invService = phosphor::power::util::getService(
71                 INVENTORY_OBJ_PATH, INVENTORY_MGR_IFACE, bus);
72 
73             // Update inventory
74             auto invMsg =
75                 bus.new_method_call(invService.c_str(), INVENTORY_OBJ_PATH,
76                                     INVENTORY_MGR_IFACE, "Notify");
77             invMsg.append(std::move(invObj));
78             auto invMgrResponseMsg = bus.call(invMsg);
79         }
80         catch (const std::exception& e)
81         {
82             log<level::ERR>(
83                 fmt::format(
84                     "Error in inventory manager call to update inventory: {}",
85                     e.what())
86                     .c_str());
87             elog<InternalFailure>();
88         }
89     }
90 };
91 
92 std::unique_ptr<GPIOInterface> createGPIO(const std::string& namedGpio);
93 
94 class GPIOReader : public GPIOInterface
95 {
96   public:
97     GPIOReader() = delete;
98     virtual ~GPIOReader() = default;
99     GPIOReader(const GPIOReader&) = default;
100     GPIOReader& operator=(const GPIOReader&) = default;
101     GPIOReader(GPIOReader&&) = default;
102     GPIOReader& operator=(GPIOReader&&) = default;
103 
104     /**
105      * Constructor
106      *
107      * @param[in] namedGpio - The string for the gpio-line-name
108      */
109     GPIOReader(const std::string& namedGpio);
110 
111     static std::unique_ptr<GPIOInterface>
112         createGPIO(const std::string& namedGpio);
113 
114     /**
115      * @brief Attempts to read the state of the GPIO line.
116      *
117      * Throws an exception if line not found, request line fails, or get_value
118      * from line fails.
119      *
120      * @return 1 for active (low/present), 0 for not active (high/not present).
121      */
122     int read() override;
123 
124   private:
125     gpiod::line line;
126 };
127 
128 } // namespace phosphor::power::psu
129