blob: 2203b92697a225167b04a476ed887c3e42a4ae24 [file] [log] [blame]
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001#pragma once
Brandon Wyman3f1242f2020-01-28 13:11:25 -06002#include "util_base.hpp"
3#include "utility.hpp"
B. J. Wyman681b2a32021-04-20 22:31:22 +00004#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>
Brandon Wyman3f1242f2020-01-28 13:11:25 -060012
13namespace phosphor::power::psu
14{
15
16class Util : public UtilBase
17{
18 public:
Brandon Wyman3f1242f2020-01-28 13:11:25 -060019 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 }
B. J. Wyman681b2a32021-04-20 22:31:22 +000030
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
92std::unique_ptr<GPIOInterface> createGPIO(const std::string& namedGpio);
93
94class 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;
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600126};
127
128} // namespace phosphor::power::psu