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