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